clllll  

# 只管主件
v, n = map(int,input().split())

# 每到一个主件,都有四种情况,主件, 主件 + 附件1, 主件 + 附件2, 主件 + 附件1 + 附件2 

primary = {} # 格式 key是物品编号,value是 价格 和 满意度  { 1: (800, 2) , 4:(400,3), 4:(500,2) } 
fujian = {}  # 格式 key 是主件物品编号, value是物品的价格和满意度 {1:[(400,5),(400,5)]}



m_all = [] # 保存当前主件 4种 选择的价格 .不一定有4种。依次是主件的价格、主件+附件1的价格、主件+附件2的价格、主件+附件1+附件2的价格 
w_all = [] # 保存当前主件 4种 的满意度。 不一定有4种。


# 构建primary 和 fujian 
for item in range(1,n + 1):
    m, w, q = map(int, input().split())
    if q == 0:
        # 主件
        primary[item] = (m,w)
    else:
        # 附件
        if q in fujian.keys():
            # 第二个附件
            fujian[q].append((m,w))
        else:
            # 第一个附件
            fujian[q] = [(m,w)]

# print("primary:", primary)
# print("fujian:", fujian)
#  构建 m 和 w 

for p in primary.keys():
    # 遍历主件 ,主件价格 追加
    m = [primary[p][0]]
    w = [primary[p][1] * m[0]]

    # 遍历当前主件的附件 
    if p in fujian.keys():
        # 主件 + 附件1  的 价格 追加 
        m.append(m[0] + fujian[p][0][0] )
        # 主件 + 附件1  的满意度 追加
        w.append(w[0] + fujian[p][0][1] * fujian[p][0][0])
        if len(fujian[p]) > 1:
            # 有附件2 

            # 主件 + 附件2 的价格 追加 
            m.append(m[0] + fujian[p][1][0])
            # 主件 + 附件2 的满意度 追加
            w.append(w[0] + fujian[p][1][1] * fujian[p][1][0])

            # 主件 + 附件1 + 附件2  的价格追加
            m.append(m[1] + fujian[p][1][0])
            # 主件 + 附件1 + 附件2  的满意度追加
            w.append(w[1] + fujian[p][1][1] * fujian[p][1][0])
    m_all.append(m)
    w_all.append(w) 

# print("m_all:", m_all)
# print("w_all:", w_all)
# 构建dp 

# dp = [[0 for i in range(v+1)] for j in range(n+1)]
dp = [[0]*(v+1) for _ in range(len(m_all)+1)]
# print("len_dp:", len(dp))
# print("len_v:", len(dp[0]))
# print("dp:", dp) 

# for i in range(1, len(m_all) + 1):
#     for j in range(10, v+1, 10):
#         max_w_ij = dp[i-1][j] # 起始最大值就是不要当前的物品的满意度
#         for current_m, current_w in zip(m_all[i-1], w_all[i-1]):
#             # 遍历当前的四种情况,可能只有一种。
#             if j - current_m >= 0:
#                 # 当前价格大于当前要买的东西 价格才 开始 比较 
#                 # print("current_i:", i, current_m, current_w )
#                 max_w_ij = max(max_w_ij, dp[i-1][j - current_m] + current_w)
        
#         dp[i][j] = max_w_ij 
dp = [0] * (v + 1)  # 滚动数组 ,计算当前行只和上一行有关系

for i in range(1, len(m_all) + 1):
    dp_pre = dp 
    dp = [0] * (v + 1) 
    for j in range(10, v+1, 10):
        max_w_ij = dp_pre[j] 
        for current_m, current_w in zip(m_all[i-1], w_all[i-1]):
            # 遍历当前的四种情况,可能只有一种。
            if j - current_m >= 0:
                # 当前价格大于当前要买的东西 价格才 开始 比较 
                # print("current_i:", i, current_m, current_w )
                max_w_ij = max(max_w_ij, dp_pre[j - current_m] + current_w)
        
        dp[j] = max_w_ij

考试最好不要用ijk,用其他带名称的变量先赋值。不然很容易在细节算错。

关于动态规划。
就是填表
从上到下,从左到右。到每一个点,有可能有多个选择,多个选择就先构造多个选择,然后遍历。

如果不好构建表,就暴力 贪婪 。

posted on 2022-12-09 23:21  llcl  阅读(24)  评论(0编辑  收藏  举报