0小明的背包6 - 蓝桥云课 (lanqiao.cn)https://www.lanqiao.cn/problems/1179/learning/
#小明背包系列6,也是最后一个,树形真的好难啊啊啊
N,V=map(int,input().split())
g = [[] for i in range(N+1)]
v = [0]*(N+1)
w = [0]*(N+1)
dp = [[0]*(V+1)for i in range(N+1)]
# v[i]表示第i个物品的体积,w[i]表示第i个物品的价值,
# g[i]表示第i个物品的父节点,
# dp[i][j]表示在前i个物品中,背包容量为j时的最大价值。
def dfs(f): #dfs(f)实现了从节点f开始的深度优先搜索,计算dp[f][j]的值
for i in range(v[f],V+ 1):
dp[f][i] = w[f]
for pp in g[f]:
dfs(pp)
for j in range(V, v[f]+v[pp]-1,-1):
for k in range(v[pp],j-v[f]+1):
if k<=j:
dp[f][j] = max(dp[f][j], dp[f][j-k]+dp[pp][k])
for i in range(1,N+1):
v[i],w[i],x=map(int,input().split())
g[x].append(i)
dfs(0)
print(dp[0][V])
'''
函数dfs(f)实现了从节点f开始的深度优先搜索,计算dp[f][j]的值。 首先,对于所有的j>=v[f],dp[f][j]的初始值为w[f],即将第f个物品放入背包中。 然后,对于f的每个子节点pp,递归调用dfs(pp),计算dp[pp][k]的值。 最后,对于所有的j>=v[f]+v[pp],更新dp[f][j]的值为dp[f][j]和dp[f][j-k]+dp[pp][k]的较大值, 其中k的取值范围为[v[pp],j-v[f]+1]。 最终,dp[0][V]即为在前N个物品中,背包容量为V时的最大价值。
'''
'''
解决背包问题。背包问题是一个经典的组合优化问题,通常有两种形式:0-1背包问题和完全背包问题。这段代码解决的是0-1背包问题。
使用了深度优先搜索(DFS)来计算背包在不同容量下的最大价值。首先,根据输入的物品信息,构建了一个有向无环图(DAG),图中每个节点表示一个物品,节点之间的边表示物品之间的包含关系。然后通过DFS遍历这个图,计算每个节点对应的最大价值。
在DFS的过程中,对于每个节点f,首先初始化背包容量为v[f]到V的最大价值为w[f](即当前节点的价值)。然后遍历节点f的子节点pp,递归计算子节点pp的最大价值,并根据子节点pp的体积和价值更新节点f的最大价值。最终得到的dp[0][V]即为在前N个物品中,背包容量为V时的最大价值。
就是动态规划算法,通过DFS遍历有向无环图,计算0-1背包问题的最优解
'''