数字王国的秩序危机
https://xinyoudui.com/ac/contest/74500D284000A6307D5E50/problem/43707
考场上调了 114514 年没有调出来直接 DP 做法,这里写一个更不需要脑子的做法。
考虑直接 DP,枚举 \(c\) 在 Trie 树上 DP 复杂度是 \(O(2^{2n})\) 级别的。
使用增量法,当我从 \(c1 \to c2\) 时,可能不需要更改这个 Trie 树的大部分 DP 值,只要更改上面若干层就可以了,那么我们对于这个东西建出搜索树,可以放一下代码:
void dfs ( int x ) {
vis[x] = 1;
if ( !x ) {
for ( int i = 0; i < n; i ++ ) {
cout << x << " " << ( 1 << i ) << '\n';
sum += ( 1 << i + 1 ) - 1;
dfs ( 1 << i );
}
}
else {
int wei = __lg ( x & -x );
for ( int i = 0; i < wei; i ++ ) {
if ( !vis[x | ( 1 << i )] ) {
cout << x << " " << ( x | ( 1 << i ) ) << '\n';
sum += ( 1 << i + 1 ) - 1;
dfs ( x | ( 1 << i ) );
}
}
}
}
那么 \(sum\) 就是增量过程中需要重构的部分大小,可以通过打表发现是 \(O(n 2^n)\) 级别的,因此我们不按照原有顺序 DP,按照搜索树 DP,时间复杂度即可做到 \(O(n 2^n)\)。

浙公网安备 33010602011771号