b_vj_末尾有最多0的乘積(類揹包)
阿新 • • 發佈:2020-11-13
給定N個正整數A1, A2, ... AN。從中選出M個整數,使得它們的乘積末尾有最多的0。
思路:f[i][j][k]表示從前i個數中選出j,且一共有k個因數5時,最多的2的個數
#include<iostream> #include<cstring> using namespace std; const int N=105; int n,m,nums[N],c5,a[N],b[N],f[N][N][1000]; //a[i]第i個數2的因子的個數 int main() { std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin>>n>>m; for (int i=1; i<=n; i++) cin>>nums[i]; for (int i=1; i<=n; i++) { while (nums[i]%2==0 && nums[i]) a[i]++, nums[i]/=2; while (nums[i]%5==0 && nums[i]) b[i]++, nums[i]/=5, c5++; } memset(f,-1,sizeof f), f[0][0][0]=0; for (int i=1; i<=n; i++) for (int j=0, t=min(i,m); j<=t; j++) for (int k=0; k<=c5; k++) { f[i][j][k]=f[i-1][j][k]; if (j && k>=b[i] && f[i-1][j-1][k-b[i]]!=-1) f[i][j][k]=max(f[i][j][k], f[i-1][j-1][k-b[i]]+a[i]); } int mx=0; for (int k=1; k<=c5; k++) mx=max(mx, min(f[n][m][k], k)); cout<<mx; return 0; }