有 NN 个物品和一个容量是 VV 的背包。
物品之间具有依赖关系,且依赖关系组成一棵树的形状。如果选择一个物品,则必须选择它的父节点。
如下图所示:
如果选择物品5,则必须选择物品1和2。这是因为2是5的父节点,1是2的父节点。
每件物品的编号是 ii,体积是 vivi,价值是 wiwi,依赖的父节点编号是 pipi。物品的下标范围是 1…N1…N。
求解将哪些物品装入背包,可使物品总体积不超过背包容量,且总价值最大。
输出最大价值。
输入格式
第一行有两个整数 N,VN,V,用空格隔开,分别表示物品个数和背包容量。
接下来有 NN 行数据,每行数据表示一个物品。
第 ii 行有三个整数 vi,wi,pivi,wi,pi,用空格隔开,分别表示物品的体积、价值和依赖的物品编号。
如果 pi=−1pi=−1,表示根节点。 数据保证所有物品构成一棵树。
输出格式
输出一个整数,表示最大价值。
数据范围
1≤N,V≤1001≤N,V≤100
1≤vi,wi≤1001≤vi,wi≤100
父节点编号范围:
- 内部结点:1≤pi≤N1≤pi≤N;
- 根节点 pi=−1pi=−1;
代码:
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class four {
static int num,bag;
static int bags[][]=new int[1010][1010],v[]=new int[1010],w[]=new int[1010];
public static void dfs(int root ,List list[]){
for (int i=v[root];i<=bag;i++){
bags[root][i]=w[root];
}
for (int i=0;i<list[root].size();i++){
int y= (int) list[root].get(i);
dfs(y,list);
for (int j=bag;j>=v[root];j--){
for (int k=0;k<=j-v[root];k++){
bags[root][j]=Math.max(bags[root][j],bags[root][j-k]+bags[y][k]);
}
}
}
}
public static void main(String[] args) {
List list[]=new List[1010];
Scanner scanner=new Scanner(System.in);
num=scanner.nextInt();
bag=scanner.nextInt();
for (int i=0;i<=num;i++){
list[i]=new ArrayList();
}
int root=0,k;
for (int i=1;i<=num;i++){
v[i]=scanner.nextInt();
w[i]=scanner.nextInt();
k=scanner.nextInt();
if (k==-1) root=i;
else list[k].add(i);
}
dfs(root,list);
System.out.println(bags[root][bag]);
}
}