树上背包

就是在树上做背包, 通常把子树的最优值当成一个一个元素, 合并他们。

\(u \to v\) 的边。

收集型伪代码

for(int i = sz[u]; ~i; i--){
	for(int j = min(sz[v], i); ~j; j--){
		dp[u][i] = max(dp[u][i], dp[u][i - j] + dp[v][j]);
	}
}

扩散型伪代码

for(int i = sz[u]; ~i; i--){
	for(int j = sz[v]; ~j; j--){
		dp2[i + j] = max(dp2[i + j], dp[u][i] + dp[v][j])
	}
}

题目 luogu P1273

直接写合并时间复杂度看似是 \(O(n^3)\), 实则是 \(O(n^2)\)

如果每一次合并都是有效的, 操作可以看做是从两个子树取出两个叶子节点合并, 最多有 \(n^2\) 次合并, 所以时间复杂度为 \(O(n^2)\)

posted @ 2024-04-25 17:05  liuyichen  阅读(4)  评论(0编辑  收藏  举报