树上背包
树上背包
给一颗树,每个节点上有一个物品,每个体积为wi,价值为vi。
选了一个点必须选它的父亲。
问总体积不超过m的情况下总价值最大值
f[u][j]代表在以u为根的子树中,选了j的体积,能得到的最大价值
·首先i一定要选
·枚举给每个子树v分配多少体积k
f[u][j]=max(f[u][j],f[u][j-k]+f[v][k])
void dfs(int fa,int x){
for(int i=w[x];i<=m;i++)
f[x][i]=v[x];
for(int i=head[x];i;i=nxt[i]){
if(to[i]==fa)
continue;
dfs(x,to[i]);
for(int j=m;j;j--)
for(int k=0;k<=j-w[x];k++)
f[x][j]=max(f[x][j],f[x][j-k]+f[to[i]][k]);
}
}
·单次转移O(m2),总复杂度O(n*m2)
·其实可以发现每个子树就是一个泛化物品