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背包就行了。

 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
",ans);
35     return 0;
36 }
View Code
原文地址:https://www.cnblogs.com/bin-gege/p/7407177.html