9.有依赖的背包问题
问题:
有N件物品和一个容量是V的背包。
物品之间具有依赖关系,且依赖关系组成一棵树的形状。如果选择一个物品,则必须选择它的父节点。
如图所示

如果选择物品5,则必须选择物品1和2,这是因为2是5的父节点,1是2的父节点。
每件物品的编号是i,体积是vi,价值是wi,依赖的父节点编号是pi。物品的下标范围是1…N.
求解将哪些物品装入背包,可使这些物品的总体积不超过背包的容量,且价值总和最大。
输出最大价值
输入格式
第一行有两个整数,N,V,用空格隔开,分别表示物品个数、背包容量。
接下来有N行,每行数据表示一个物品
第i行有三个整数vi,wi,pi,用空格隔开,分别表示物品的体积、价值和依赖的物品编号。
如果pi=-1,表示根节点,数据保证所有物品构成一棵树。
输出格式
输出一个整数,表示最大价值
数据范围
1<N,V<=100
0<vi,wi<=100
父节点编号范围:
内部节点:1<=pi<=N;
根节点:pi=-1;
输入样例
5 7
2 3 -1
2 2 1
3 5 1
4 7 2
3 6 2
输出样例
11
分析思路:
背包和树形Dp结合(转化为分组背包问题)
每个结点,把它们对应的子节点都递归计算一下,算出每个子节点不同体积下的最大价值;,每个子节点都是一个物品组,不同体积对应到不同组;整个组里面只能选择一个物品
f[i][j]表示选结点i的情况下,所用的体积是j的情况下,以i为根的整棵子树的最大价值是多少
从上往下递归求解,每做完一个结点,先把它的所有子节点的f[i][j]都算出,每个子节点对应在不同体积下,它们要对应的价值
for(int j=m-v[u];j>=0;j--) //枚举体积 ,(m减当前物品的体积)留一个空位,从大到小(只能选一次)
若体积大于等于当前物品体积,需要在之前空出的位置,把这个物品加进去
f[u][i-v[u]]+w[u];更新的价值
若体积小于等于当前物品体积,整个子树一个节点都不选择(依赖性)
for(int k=0;k<=j;k++) //枚举物品组里面的每个物品
f[u][j]=max(f[u][j],f[u][j-k]+f[son]

本文探讨了有依赖的背包问题,这是一种结合背包问题与树形动态规划(DP)的复杂优化问题。文章详细解析了如何通过树形DP将问题转化为分组背包问题,进而求解在给定背包容量下,选择哪些具有依赖关系的物品能获得最大价值。通过实例讲解了算法的实现过程,包括输入输出格式、数据范围及代码实现。
最低0.47元/天 解锁文章
884

被折叠的 条评论
为什么被折叠?



