社区讨论

为什么以及怎样用上下界优化保证平方复杂度

P3177[HAOI2015] 树上染色参与者 5已保存回复 9

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
9 条
当前快照
1 份
快照标识符
@lo13be8d
此快照首次捕获于
2023/10/22 14:30
2 年前
此快照最后确认于
2024/07/12 19:34
2 年前
查看原帖
本题是典型的树上背包,正确的算法复杂度是O(nk)O(nk),其中nn是树的大小,kk是可选的物品数量。subtask1是用来卡O(n3)O(n^3)的错误写法的(不开O2的情况下)。在我正确通过了subtask1之后,我终于想通了为啥以及如何正确地做上下界优化,特发此贴以帮助后面卡在这里的人思考。
正如很多别的复杂度分析的文章指出,只要单个子树的算法复杂度是O(n2)O(n^2)的,那么在dp数组限制上界到kk之后,整体算法复杂度就是O(nk)O(nk)。这一点不再赘述。本贴核心在于怎么控制子树复杂度到O(n2)O(n^2)
暂且不考虑dp数组上界控制到kk的优化。每个子树的dp数组上界开到nin_i,即该子树大小;于是,n=i=1knin=\sum_{i=1}^kn_i。设对大小为nn的树复杂度是T(n)T(n),那么应该有T(n)=i=1kT(ni)+M(n1,,nk)T(n)=\sum_{i=1}^kT(n_i)+M(n_1,\cdots,n_k),其中M()M(\cdot)是合并步的复杂度。
一种(可能)正确的写法如下。
CPP
int sz = 1;
for (const auto& [nt, w]: gr[cr]) {
	if (nt==pa) continue;
	auto [cnt, ndp] = dfs(dfs, nt, cr);
	for (int i = min(sz+cnt, k); i>=0; --i) {
		for (int j = max(0, i-min(sz, k)); j<cnt && j<=i; ++j) {
			dp[i] = max(dp[i], dp[i-j]+ndp[j]+1LL*w*(j*(k-j)+(cnt-j)*(n-cnt-k+j)));
		}
	}
}
为什么这样是对的?因为(继续忽略kk)我们需要把循环控制在{(i,j):0isz+cnt,max{0,isz}jmin{cnt,i}}\{(i,j):0\le i\le sz+cnt,\max\{0,i-sz\}\le j\le \min\{cnt,i\}\}内,这是一个平行四边形(请自行画图),所以总的大小是(1+sz)(1+cnt)(1+ni)(1+j=1i1nj)(1+sz)(1+cnt)\le(1+n_i)(1+\sum_{j=1}^{i-1}n_j)。适当牺牲严谨性但便于表达,扔掉括号里的11,这样只会扩大后面大O里的系数。那么,可归纳证明T(n)n2T(n)\le n^2。因为,T(n)i=1kT(ni)+i=1knij=1i1nj<=i=1kni2+2i=1kj=1i1ninj=n2T(n)\le\sum_{i=1}^kT(n_i)+\sum_{i=1}^kn_i\sum_{j=1}^{i-1}n_j<=\sum_{i=1}^kn_i^2+2\sum_{i=1}^k\sum_{j=1}^{i-1}n_in_j=n^2。在加上一堆一次项和常数项后,不会改变这个阶的判断。
一个常见的错误写法如下:
CPP
int sz = 1;
for (const auto& [nt, w]: gr[cr]) {
	if (nt==pa) continue;
	auto [cnt, ndp] = dfs(dfs, nt, cr);
	for (int i = min(sz+cnt, k); i>=0; --i) {
		for (int j = 0; j<cnt && j<=i; ++j) {
			dp[i] = max(dp[i], dp[i-j]+ndp[j]+1LL*w*(j*(k-j)+(cnt-j)*(n-cnt-k+j)));
		}
	}
}
它丢掉了j的下界控制。这样会给上面的平行四边形加个小三角,变成一个梯形。这个小小的三角形看似并没有改变合并步的复杂度,但是确实给整体复杂度提升了一个阶。此时算法复杂度大致是T(n)=i=1kT(ni)+n2/2T(n)=\sum_{i=1}^kT(n_i)+n^2/2。如果树大致是平衡的,那么可以参考主定理,整体算法仍然是O(n2)O(n^2)的。但是,对于极度不平衡的树,比如一个链,算法复杂度将满足T(n)=T(n1)+T(1)+n2/2T(n)=T(n-1)+T(1)+n^2/2,此时必然有T(n)=Θ(n3)T(n)=\Theta(n^3),将完全无法接受。
所以请控制好上下界。

回复

9 条回复,欢迎继续交流。

正在加载回复...