Educational Codeforces Round 26 D. Round Subset(dp)
题目链接:Educational Codeforces Round 26 D. Round Subset
题意:
给你n个数,让你选其中的k个数,使得这k个数的乘积的末尾的0的个数最大。
题解:
显然,末尾乘积0的个数和因子2和因子5的个数有关。
然后考虑dp[i][j]表示选i个数,当前因子5的个数为j时,能得到因子2最多的为多少。
那么对于每个数,记录一下因子2和5的个数,做一些01背包就行了。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 #define mst(a,b) memset(a,b,sizeof(a)) 3 #define F(i,a,b) for(int i=a;i<=b;++i) 4 using namespace std; 5 typedef long long ll; 6 typedef pair<int,int>P; 7 8 const int N=207; 9 int n,m,dp[N][3607],all; 10 P a[N]; 11 ll x; 12 13 int main(){ 14 scanf("%d%d",&n,&m); 15 F(i,1,n) 16 { 17 scanf("%lld",&x); 18 int cnt2=0,cnt5=0; 19 while(x%5==0)x/=5,cnt5++; 20 while(x%2==0)x/=2,cnt2++; 21 a[i]=P(cnt5,cnt2); 22 all+=cnt5; 23 } 24 mst(dp,-1);dp[0][0]=0; 25 F(i,1,n) 26 { 27 for(int j=m;j>=1;j--) 28 for(int k=all;k>=a[i].first;k--) 29 if(dp[j-1][k-a[i].first]!=-1) 30 dp[j][k]=max(dp[j][k],dp[j-1][k-a[i].first]+a[i].second); 31 } 32 int ans=0; 33 F(j,1,all)ans=max(ans,min(j,dp[m][j])); 34 printf("%d\n",ans); 35 return 0; 36 }