题解 | #购物单#

购物单

http://www.nowcoder.com/practice/f9c6f980eeec43ef85be20755ddbeaf4

购物车是动态规划的经典之作,本题是01背包的变种,其实差别就体现在多四种判断

while True:
    try:
        l1 = list(map(int, input().split()))
        money = int(l1[0] / 10)
        tt = [[0, 0, 0] for i in range(l1[1])]  # 价格
        vi = [[0, 0, 0] for i in range(l1[1])]  # 满意度
        for i in range(l1[1]):
            res = list(map(int, input().split()))
            if res[2] != 0:
                if tt[res[2] - 1][1] == 0:
                    tt[res[2] - 1][1] = int(res[0] / 10)
                    vi[res[2] - 1][1] = res[1] * int(res[0] / 10)
                else:
                    tt[res[2] - 1][2] = int(res[0] / 10)
                    vi[res[2] - 1][2] = res[1] * int(res[0] / 10)
            else:
                tt[i][0] = int(res[0] / 10)
                vi[i][0] = res[1] * int(res[0] / 10)

        for i in range(l1[1]):
            if [0, 0, 0] in tt:
                tt.remove([0, 0, 0])

        for i in range(l1[1]):
            if [0, 0, 0] in vi:
                vi.remove([0, 0, 0])

        # print(tt, vi)
        dp = [[0] * (money + 1) for i in range(len(tt) + 1)]

        for i in range(1, len(tt) + 1):
            for j in range(money + 1):
                j0, j1, j2 = tt[i - 1]
                w0, w1, w2 = vi[i - 1]

                # 关键一步,先把上一次的最优解搬过来 最优低保
                dp[i][j] = dp[i-1][j]

                # 判断上一步最优解和 剩余空间最优解+上一步最优解 谁更优 如果比不过至少有个低保
                # 如果直接 dp[i][j] = max(dp[i - 1][j - j0] + w0, dp[i-1][j]) 比不过就没低保为0

                # 灵活变通
                # 如果 dp[i][j] = max(dp[i][j - j0] + w0, dp[i][j]) 则是有放回的拿 价值会更高
                
                if j >= j0:
                    dp[i][j] = max(dp[i - 1][j - j0] + w0, dp[i][j])

                if j >= j0 + j1:
                    dp[i][j] = max(dp[i - 1][j - j0 - j1] + w0 + w1, dp[i][j])

                if j >= j0 + j2:
                    dp[i][j] = max(dp[i - 1][j - j0 - j2] + w0 + w2, dp[i][j])

                if j >= j0 + j1 + j2:
                    dp[i][j] = max(dp[i - 1][j - j0 - j1 - j2] + w0 + w1 + w2,
                                   dp[i][j])

        # print(dp)
        print(dp[-1][-1] * 10)

    except EOFError:
        break
# 1000 5
# 800 2 0
# 400 5 1
# 200 5 1
# 400 3 0
# 500 2 0


全部评论

相关推荐

不愿透露姓名的神秘牛友
昨天 17:24
点赞 评论 收藏
分享
06-25 09:33
厦门大学 Java
程序员饺子:现在日常估计没啥hc了,等到八月多估计就慢慢有了。双九✌🏻不用焦虑的
投递快手等公司7个岗位
点赞 评论 收藏
分享
07-02 10:39
门头沟学院 Java
Steven267:说点真实的,都要秋招了,还没有实习,早干嘛去了,本来学历就差,现在知道急了,而且你这个简历完全可以写成一页,劣势太大了,建议转测试
点赞 评论 收藏
分享
评论
4
收藏
分享

创作者周榜

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