题解 | #购物单# 背包问题 状态转移矩阵

购物单

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

'''
背包问题:体积V,i种物品,物品体积w(i)物品价值v,求背包能容纳下的物品最大价值。
f[i][j]=max{f[i-1][j],f[i-1][j-w(i)]+v(i)}
f[i][j]:从i个物品中选取,能放入体积为j的背包的最大价值
两种选择:第i个物品放不进体积为j的背包,最大价值为f[i-1][j]
         第i个物品放得进体积为j的背包(j>w(i)),最大价值为f[i-1][j-w(i)]+v(i)
最后简化到基准f[0][...]=0
            f[...][0]=0
'''

num=input().split()
N=int(num[0])
m=int(num[1])
main={}  #主件
annex={} #附件
for i in range(1,m+1):
    x,y,z=map(int,input().split())
    if z==0: # 主件
        main[i]=[x,y]
    else:    # 附件
        if z in annex:
            annex[z].append([x,y])
        else:
            annex[z]=[[x,y]]

m=len(main)

v=[[]] #价格
s=[[]] #满意度=价格*重要度
for key in main:
    v0,s0=[],[]  # 临时记录表
    v0.append(main[key][0])
    s0.append(main[key][0]*main[key][1])
    if key in annex.keys(): 
        # 附件对应的主件存在(主件、主件+附件1、主件+附件2、主件+附件1+附件2)
        v0.append(v0[0]+annex[key][0][0])  #主件+附件1
        s0.append(s0[0]+annex[key][0][0]*annex[key][0][1])
        if len(annex[key])>1:
            v0.append(v0[0]+annex[key][1][0])  #主件+附件2
            s0.append(s0[0]+annex[key][1][0]*annex[key][1][1])
            v0.append(v0[0]+annex[key][0][0]+annex[key][1][0]) #主件+附件1+附件2
            s0.append(s0[0]+annex[key][0][0]*annex[key][0][1]+annex[key][1][0]*annex[key][1][1])
    v.append(v0)
    s.append(s0)
#print(v)
#print(s)
# 状态转移方程
dp=[[0]*(N+1) for _ in range(m+1)]
#print(len(dp[0]))
for i in range(1,m+1):
    for j in range(10,N+1,10): 
        #每件物品的价格(都是 10 元的整数倍),N元以内的最大满意度,所构成的最终金额必定是10 的倍数
        max_i=dp[i-1][j]
        for k in range(len(v[i])):
            if j-v[i][k]>=0:
                max_i=max(max_i,dp[i-1][j-v[i][k]]+s[i][k])
        dp[i][j]=max_i

print(dp[m][N])
#print(dp)





全部评论

相关推荐

09-18 20:41
百度_Java
要个offer怎么这...:哈哈哈哈哈哈,我也拿了0x10000000个offer,秋招温啦啦啦,好开心
我的秋招日记
点赞 评论 收藏
分享
迷茫的大四🐶:都收获五个了,兄弟那还说啥,不用改了,去玩吧
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

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