n数,从中选k个,使得它们乘积的后缀零最多
dp[i][j][k]表示(扫描前i个,从中选出j个,得到5的幂次为k)的2的幂次的值,类似背包问题
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 #define INF 0x3f3f3f3f 6 using namespace std; 7 typedef long long LL; 8 const int maxn = 2e2 + 10; 9 const int maxm = 2e2 * 30; 10 int dp[maxn][maxm]; 11 int N, K; 12 13 int main() { 14 scanf("%d%d", &N, &K); 15 LL A; 16 for (int i = 0; i < maxn; i++) for (int j = 0; j < maxm; j++) dp[i][j] = -INF; 17 dp[0][0] = 0; 18 for (int i = 1; i <= N; i++) { 19 scanf("%lld", &A); 20 LL B = A; 21 int p2 = 0; 22 int p5 = 0; 23 while (!(B % 2)) { 24 p2++; 25 B /= 2; 26 } 27 while (!(A % 5)) { 28 p5++; 29 A /= 5; 30 } 31 for (int j = K; j >= 1; j--) { 32 for (int k = p5; k < maxm; k++) { 33 dp[j][k] = max(dp[j][k], dp[j - 1][k - p5] + p2); 34 } 35 } 36 } 37 int ans = 0; 38 for (int i = 1; i < maxm; i++) { 39 ans = max(ans, min(i, dp[K][i])); 40 } 41 printf("%d\n", ans); 42 return 0; 43 }