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