Loading

数字王国的秩序危机

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)\)

posted @ 2026-01-23 15:52  Alexande  阅读(1)  评论(0)    收藏  举报