树上背包

树上背包

给一颗树,每个节点上有一个物品,每个体积为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)
·其实可以发现每个子树就是一个泛化物品

posted @ 2022-02-12 16:08  su-yichen  阅读(44)  评论(0编辑  收藏  举报