0%

CF837D Round Subset

Round Subset - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

Solution

问题转化为:设取的 kk 个数的因子中共有 xx22yy55。选择取数的方案,使得 min{x,y}\min\{x,y\} 最大化。

Fi,jF_{i,j} 表示取了 ii 个数,其中含有 jj55 的方案所能取到的 22 的最大数量。用 01 背包进行转移。

由于 1018<53010^{18}<5^{30},所以 FF 第二维大小开到 30×20030\times 200

时间复杂度 O(n3logai)O(n^3\log a_i)

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const ll N = 205;

ll n, k, f[N][35 * N], x[N], y[N], ans;

int main()
{
scanf("%lld%lld", &n, &k);
memset(f, -1, sizeof(f));
for (int i = 1; i <= n; i++) {
ll num;
scanf("%lld", &num);
while (num % 2 == 0) {
x[i]++;
num >>= 1;
}
while (num % 5 == 0) {
y[i]++;
num /= 5;
}
}
f[0][0] = 0;
for (int i = 1; i <= n; i++) {
for (int j = 30 * N; j >= y[i]; j--) {
for (int l = k; l >= 1; l--) {
if (f[l - 1][j - y[i]] != -1)
f[l][j] = max(f[l][j], f[l - 1][j - y[i]] + x[i]);
}
}
}
for (int i = 1; i <= 30 * N; i++)
ans = max(ans, min((ll)i, f[k][i]));
printf("%lld", ans);
return 0;
}