动态规划

外卖小哥的保温箱

http://www.nowcoder.com/questionTerminal/f3826b317d094e17a04e64a402bd0866

这道题整了一晚上,最后看大佬@Albert7 代码思考人生,才想出来怎么做,现在分享一下菜鸡思路
博客链接https://blog.csdn.net/qq_28597451/article/details/104691882
昨天在牛客网上做笔试题,碰到了一道题动态规划做了一晚上都没做出来,最后看着别人的答案才勉强做出来,太菜了,今天总结一下。

动态规划思路:
1、找到状态和选择,确定当前状态和转换
2、明确dp数组/或函数的定义,即dp数组保存了啥信息(dp数组一般是一维或二维)
3、寻找状态之间的关系,当前状态如何根据上一状态和一些已知信息得到(状态转换方程)

下面是解题思路

从题目可以了解到,我们需要做的是:
1、找出需要的最少的k个保温箱,使得这个k个保温箱可以装下所有的货物;
2、确定转移货物的最少时间,所以所找到的k个保温箱中所包含的货物尽可能多,则需要转移货物就越少,时间越短;

输入代码:

import sys
inp = []
while True:
    line = sys.stdin.readline().strip()
    if line == '':
        break
    line = (line.split(' '))
    inp.append([int(line[i]) for i in range(len(line))])
n = inp[0][0]
food = inp[1]
capacity = inp[2]

上面的输入莫名奇妙就爆bug了,通过不了,大概可能是原来是牛客网的输入可能混杂了空行或者为空,所以输入就出错误了,以后注意点。下面是正确(可以通过的)读取输入代码

import sys
n = int(input().strip())
lines = sys.stdin.readlines()
if len(lines) == 1:
    temp = list(map(int, lines[0].strip().split()))
    food = temp[:n]
    capacity = temp[n:]
else:
    food = list(map(int, lines[0].strip().split()))
    capacity = list(map(int, lines[1].strip().split()))
max_food = sum(food)
max_capacity = sum(capacity)

1、定义一个dp[capacity][2]数组,dp[i] = [k,food] 保存总容量为i的保温箱最少可以由k个保温箱组成,而且保温箱原来的总货物为food,应该是最大的;并初始化k的值为最大值(保温箱的数目)然后一步一步减小
2、转换方程:因为我们要保证使用的保温箱是最少的,对于第k个保温箱,当前最大容量为i,它是由容量max(i-capacity[k-1], 0)来决定的,

for k in range(1, n+1): # 对于每一个保温箱
    for i in range(max_capacity, 0, -1): # 对于当前容量最大的,从最大容量倒序
        count = dp[max(i - capacity[k-1], 0)][0]
        weight = dp[max(i - capacity[k-1], 0)][1]
        if dp[i][0] < count+1:  # 保证当前所需要的保温箱最少
            continue
        elif dp[i][0] > count+1:   # 比当前所需要的保温箱少,更新当前所选择保温箱数,货物数为之前加上当前保温箱的货物,不用比较大小,因为所需保温箱数比之前少,优先级更高
            dp[i][0] = count + 1
            dp[i][1] = weight + food[k-1]
        else: # 两者相等,取最大值
            dp[i][1] = max(weight + food[k - 1], dp[i][1])

3、寻找最优值,找到从大于等于当前货物数的容量区间[max_food, max_capacity]中,从需要箱子最少中找出货物最多的

min_step = 0
min_bin = n
for i in range(max_food, max_capacity+1):
    if dp[i][0] < min_bin:
        min_bin = dp[i][0]
        min_step = dp[i][1]
    elif dp[i][0] == min_bin:
        min_step = max(dp[i][0], min_step)
min_step = max_food - min_step

总的代码

import sys
n = int(input().strip())
lines = sys.stdin.readlines()
if len(lines) == 1:
    temp = list(map(int, lines[0].strip().split()))
    food = temp[:n]
    capacity = temp[n:]
else:
    food = list(map(int, lines[0].strip().split()))
    capacity = list(map(int, lines[1].strip().split()))

max_food = sum(food)
max_capacity = sum(capacity)
dp = [[len(food), 0] for _ in range(max_capacity+1)]
dp[0] = [0, 0]

for k in range(1, n+1):
    for i in range(max_capacity, 0, -1):
        count = dp[max(i - capacity[k-1], 0)][0]
        weight = dp[max(i - capacity[k-1], 0)][1]
        if dp[i][0] < count+1:
            continue
        elif dp[i][0] > count+1:
            dp[i][0] = count + 1
            dp[i][1] = weight + food[k-1]
        else:
            dp[i][1] = max(weight + food[k - 1], dp[i][1])
print(dp[:][:])

min_step = 0
min_bin = n
for i in range(max_food, max_capacity+1):
    if dp[i][0] < min_bin:
        min_bin = dp[i][0]
        min_step = dp[i][1]
    elif dp[i][0] == min_bin:
        min_step = max(dp[i][0], min_step)
min_step = max_food - min_step
# print(max_food, min_step)
print(str(min_bin) + ' ' + str(min_step))
全部评论
就应该从总货物倒序,我觉得。这样复杂度还小些
点赞 回复 分享
发布于 2020-03-27 11:27
为什么要从最大容量(sum(b))倒序而不是从总货物数(sum(a))倒序呢
点赞 回复 分享
发布于 2020-03-12 00:33

相关推荐

一天代码十万三:这个学历有中大厂实习也是0面,没办法,斩杀线是这样的
点赞 评论 收藏
分享
真tmd的恶心,1.面试开始先说我讲简历讲得不好,要怎样讲怎样讲,先讲背景,再讲技术,然后再讲提升多少多少,一顿说教。2.接着讲项目,我先把背景讲完,开始讲重点,面试官立即打断说讲一下重点,无语。3.接着聊到了项目的对比学习的正样本采样,说我正样本采样是错的,我解释了十几分钟,还是说我错的,我在上一家实习用这个方法能work,并经过市场的检验,并且是顶会论文的复现,再怎么不对也不可能是错的。4.面试官,说都没说面试结束就退出会议,把面试者晾在会议里面,丝毫不尊重面试者难受的点:1.一开始是讲得不好是欣然接受的,毕竟是学习。2.我按照面试官的要求,先讲背景,再讲技术。当我讲完背景再讲技术的时候(甚至已经开始蹦出了几个技术名词),凭什么打断我说讲重点,是不能听出人家重点开始了?这也能理解,每个人都有犯错,我也没放心上。3.我自己做过的项目,我了解得肯定比他多,他这样贬低我做过的项目,说我的工作是错误的,作为一个技术人员,我是完全不能接受的,因此我就和他解释,但无论怎么解释都说我错。凭什么,作为面试官自己不了解相关技术,别人用这个方式work,凭什么还认为这个方法是错的,不接受面试者的解释。4.这个无可厚非,作为面试官,不打招呼就退出会议,把面试者晾着,本身就是有问题。综上所述,我现在不觉得第一第二点也是我的问题,面试官有很大的问题,就是专门恶心人的,总结面试官说教,不尊重面试者,打击面试者,不接受好的面试者,技术一般的守旧固执分子。有这种人部门有这种人怎么发展啊。最后去查了一下,岗位关闭了。也有可能是招到人了来恶心人的,但是也很cs
牛客20646354...:招黑奴啊,算法工程师一天200?
点赞 评论 收藏
分享
评论
8
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务