CF837D Round Subset

我们把一个数的 roundness 值定义为它末尾 \(0\) 的个数。

给你一个长度为 \(n\) 的数列,要求你从中选出 \(k\) 个数,使得这些选出的数的积的 roundness 值最大。

\(k \le n \le 200\)\(a_i \le 10^{18}\)

显然答案是取出的数中,所有 \(2\) 的出现次数和 \(5\) 的出现次数的 \(\min\)

DP。

\(\min\) 非常不好维护。不尝试将 \(\min\) 放在状态/值里。

于是我们尝试把下面这 \(4\) 个值放在 DP 里:

  • \(i\):考虑前 \(i\) 个数;
  • \(j\):选 \(j\) 个;
  • \(a\):出现过 \(a\)\(2\)
  • \(b\):出现过 \(b\)\(5\)

最暴力的是状态四维,值为 bool。复杂度 \(\mathcal O(n^4 \log_2 V \log_5 V)\)。爆。

稍微好一点的,形如 \(f(i,a,b)=j\),表示前 \(i\) 个数,出现 \(a\)\(2\)\(b\)\(5\),最少需要选几个数。这样能做到 \(\mathcal O(n^3 \log_2 V \log_5 V)\)。还是爆。

经过一些尝试,发现 \(f(i,j,b)=a\) 是最优的,表示前 \(i\) 个数,选了 \(j\) 个,其中有 \(b\)\(5\)\(2\) 最多几个。原因是 \(a\) 的上限最大(\(\log_2 V\))。于是复杂度是 \(\mathcal O(n^3 \log_5 V)\)

但是空间炸。加个滚动就好啦。

答案是:

\[\max \min(i,f(n,k,i)) \]

posted @ 2024-11-12 14:05  2huk  阅读(1)  评论(0编辑  收藏  举报