题解 | #购物单# 动态规划,记忆化搜索+dfs

购物单

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

from functools import cache
from math import inf
import collections
n, m = map(int, input().split())
d = {}  # major下标对应主件的实际编号
sub = collections.defaultdict(list) # 每个主件编号对应附件 在minor中的下标 组成的数组
major = []  # 主件价格,重要度
minor = []  # 附件价格,重要度
for i in range(m):
    g = list(map(int, input().split()))
    if g[2] == 0:
        major.append([g[0], g[1]])
        d[len(major) - 1] = i + 1 # major -> i
    else:
        minor.append([g[0], g[1]])
        sub[g[2]].append(len(minor) - 1)    # i -> minor
# print(major, minor)
# print(d, sub)
@cache
def dfs(i, cost):   # major中,前i个在总费用cost下的最大满意度
    if cost < 0:
        return -inf
    if i < 0:
        return 0
    idx = d[i]
    ans = dfs(i - 1, cost)  # 不买第i件物品

    # 买第i件物品
    val = major[i][0] * major[i][1]
    cost -= major[i][0]
    sub_g = sub[idx]
    cd = [] # 第i件物品对应附件的所有情况,[附件总花费, 附件总满意度]
    tmp = [0, 0]    # cd的添加项
    def sub_dfs(j): # 代价是什么,附件的所有情况
        # print(j)
        nonlocal cd, tmp
        if j < 0:
            cd.append(tmp)
            return
        sub_dfs(j - 1)  # 不买第j个附件

        # 买第j个附件
        tmp = [tmp[0] + minor[sub_g[j]][0], tmp[1] + minor[sub_g[j]][0] * minor[sub_g[j]][1]]
        sub_dfs(j - 1)
        tmp = [tmp[0] - minor[sub_g[j]][0], tmp[1] - minor[sub_g[j]][0] * minor[sub_g[j]][1]] # 恢复现场
        return
    sub_dfs(len(sub_g) - 1)
    # print(i, cd, sub_g)
    for c in cd:    # 第i个主件和对应附件的所有买入情况,取最大满意度
        ans = max(ans, dfs(i - 1, cost - c[0]) + val + c[1])
    return ans


ans = dfs(len(major) - 1, n)
print(ans)

全部评论

相关推荐

点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务