如何解决如何解决背包问题的这个变体?
我正在尝试解决这个问题:邮局有 n customers
人在排队等待寄送包裹。 a[0],a[1],...,a[n-1]
是从第 1 人到第 n 人的 n 个客户的运费列表。邮政工作人员只需一分钟即可完成客户寄送包裹所需的信息。但是,所有客户都太忙了,无法等待超过一定时间。 t[0],t[1],t[n-1]
是 n 个客户中每个人可以在邮局花费的分钟数列表。帮助邮政工作人员找到一种为客户服务的方法,以便邮局可以得到最大的钱,知道员工可以以盈利为由拒绝为一些客户服务。)
示例:
- 对于
a = [10,20,5,12],t = [2,3,1]
,输出应为42
。 说明:客户的顺序是:第4个人->第1个人->第2个人(基于1的索引) - 对于
a = [5,1,2],t = [3,2,2]
,输出应为10
。 说明:虽然第2个人只能等1分钟,但这个人要付出最小的代价。因此,邮政工作人员不会为该客户服务。顾客的顺序是:第三人->第四人->第一人。
我认为这是背包问题的一种变体,我可以使用蛮力解决它,但仅限于小输入。有人可以帮我解决这个问题吗?谢谢。
解决方法
如果没有重叠的时间,问题很简单,只需将所有运费相加即可。如果有重叠,问题就变得不重要了。
所以让我们形成一个(时间,成本)的元组,并首先按时间排序,然后按成本(降序)排序。
例如输入:
a = [10,20,5,12]
t = [2,3,1]
已排序的元组列表将是:
[(1,12),(2,10),(3,20),5)]
现在让我们有一个运行的成本清单。
对于 (1,12) 我们的列表将是 [12]
对于 (2,10) 因为 2 不等于 1,您可以将成本 (10) 添加到您的列表中 [12,10]
对于 (3,20) 因为 3 不等于 2,您只需将 20 添加到列表中即可使其成为 [12,10,20]
对于 (3,5) 我们有重叠,有两个选项:
-
去掉其中一项 - 列表中的最小值,即 10 并添加 5
-
跳过 5
第二种选择会更好。 最终列表将是 [12,20],其 sum = 42 就是答案。
注意这里列表的长度总是等于每次的时间 t。这是合乎逻辑的,因为您只能在时间 t 之前处理 t 个客户,而问题是在该列表中找到最佳成本。
再举个例子:
a = [10,7,15,1]
t = [2,2,1]
[(1,1),7),5),15)]
对于这个,运行列表将如下所示:
t = 1 : [1] # 刚开始推
t = 2 : [1,10] # 2 > 1 所以推
t = 2 : [7,10] # 2 的重叠,看 1 能不能去掉,7 能不能加 yes so push
t = 2 : [7,10] # 2的重叠,看7能不能去掉,5能不能加,不,因为会减少利润。所以保留清单。
t = 3 : [7,20] # 3 > 2,直接推
t = 3 : [10,15] # 3的重叠,看能不能去掉min加15,是的然后去掉7加15。
答案是 45。
python 中的代码如下:
import heapq
def get_max_shipping_cost(a,t):
if len(a) == 0:
return 0
items = sorted(zip(t,a),key = lambda tup: (tup[0],-tup[1]))
l = []
heapq.heappush(l,items[0][1])
s = items[0][1]
i = 1
prev = items[0]
while i < len(items):
if items[i][0] == prev[0]:
prev = items[i]
if s - l[0] + items[i][1] > s:
s = s - l[0] + items[i][1]
heapq.heappop(l)
heapq.heappush(l,items[i][1])
i += 1
elif items[i][0] == prev[0] + 1:
prev = items[i]
heapq.heappush(l,items[i][1])
s += items[i][1]
i += 1
else:
prev = (prev[0] + 1,0)
heapq.heappush(l,0)
return s
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。