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\n",ans);
35     return 0;
36 }

时间: 2024-10-03 13:46:16

Educational Codeforces Round 26 D. Round Subset(dp)的相关文章

Educational Codeforces Round 26 D. Round Subset 动态规划

D. Round Subset Let's call the roundness of the number the number of zeros to which it ends. You have an array of n numbers. You need to choose a subset of exactly k numbers so that the roundness of the product of the selected numbers will be maximum

【动态规划】【滚动数组】Educational Codeforces Round 26 D. Round Subset

给你n个数,让你任选K个,使得它们乘起来以后结尾的0最多. 将每个数的因子2和因子5的数量求出来,记作a[i]和b[i]. 答案就是max{ min{Σa[i],Σb[i]} }(a[i],b[i]是选择的那些数). 暴力dp是f(i,j,k)表示前i个数,选j个,其中包含k个5的情况下,最多能包含多少个2. 转移是f(i,j,k)=max{ {f(t,j-1,k-b[i]}+a[i]}(1<=i<t) , f(i-1,j,k) },时间是O(18 * n^3),但空间存不下. 注意第二维为j

Educational Codeforces Round 26 D dp,思维

Educational Codeforces Round 26 D. Round Subset 题意:有 n 个数,从中选出 k 个数,要使这 k 个数的乘积末尾的 0 的数量最多. tags:dp好题 dp[i][j][l] 表示前 i 个数,选取了其中 j 个数,分解因子后有 l 个 5时,最多有多少个 2 .i 这一维明显可以省略. 这题一开始有个地方写挫了..选取 j 个数时,应该反着来,即 for( j, k, 1) ,不是 for( j, 1, k) ,不然会多算. #include

Educational Codeforces Round 21 G. Anthem of Berland(dp+kmp)

题目链接:Educational Codeforces Round 21 G. Anthem of Berland 题意: 给你两个字符串,第一个字符串包含问号,问号可以变成任意字符串. 问你第一个字符串最多包含多少个第二个字符串. 题解: 考虑dp[i][j],表示当前考虑到第一个串的第i位,已经匹配到第二个字符串的第j位. 这样的话复杂度为26*n*m*O(fail). fail可以用kmp进行预处理,将26个字母全部处理出来,这样复杂度就变成了26*n*m. 状态转移看代码(就是一个kmp

Educational Codeforces Round 25 F. String Compression(kmp+dp)

题目链接:Educational Codeforces Round 25 F. String Compression 题意: 给你一个字符串,让你压缩,问压缩后最小的长度是多少. 压缩的形式为x(...)x(...)  x表示(...)这个出现的次数. 题解: 考虑dp[i]表示前i个字符压缩后的最小长度. 转移方程解释看代码,这里要用到kmp来找最小的循环节. 当然还有一种找循环节的方式就是预处理lcp,然后通过枚举循环节的方式. 这里我用的kmp找的循环节.复杂度严格n2. 1 #inclu

CodeForces 837F - Prefix Sums | Educational Codeforces Round 26

按tutorial打的我血崩,死活挂第四组- - 思路来自FXXL /* CodeForces 837F - Prefix Sums [ 二分,组合数 ] | Educational Codeforces Round 26 题意: 设定数组 y = f(x) 使得 y[i] = sum(x[j]) (0 <= j < i) 求初始数组 A0 经过多少次 f(x) 后 会有一个元素 大于 k 分析: 考虑 A0 = {1, 0, 0, 0} A1 = {1, 1, 1, 1} -> {C(

CodeForces - 837E - Vasya&#39;s Function | Educational Codeforces Round 26

/* CodeForces - 837E - Vasya's Function [ 数论 ] | Educational Codeforces Round 26 题意: f(a, 0) = 0; f(a, b) = 1 + f(a, b-gcd(a, b)); 求 f(a, b) , a,b <= 1e12 分析: b 每次减 gcd(a, b) 等价于 b/gcd(a,b) 每次减 1 减到什么时候呢,就是 b/gcd(a,b)-k 后 不与 a 互质 可先将 a 质因数分解,b能除就除,不能

Educational Codeforces Round 26 E - Vasya&#39;s Function

数论题还是好恶心啊. 题目大意:给你两个不超过1e12的数 x,y,定义一个f ( x, y ) 如果y==0 返回 0 否则返回1+ f ( x , y - gcd( x , y ) ); 思路:我们设gcd ( x , y) 为G,那么 设 x  = A*G,y = B*G,我们考虑减去多少个G时x y 的gcd会改变,我们设减去 k个G的时候 x和y 的gcd为改变,即 A*G 和 ( B - k ) * G 的 gcd 改变了,什么情况下会改变呢,就是A 和( B -  k )的gcd

Educational Codeforces Round 25 G. Tree Queries

题目链接:Educational Codeforces Round 25 G. Tree Queries 题意: 给你一棵树,一开始所有的点全是黑色,有两种操作. 1 x 将x这个点变为黑色,保证第一个操作是这个. 2 x 询问x到任意黑色的点的简单路径上的最小节点编号. 题解: 首先将一个变为黑色的点当成树根,然后dfs一下,预处理出所有点的答案. 然后开一个变量记录一下当前变黑的点的答案cur=min(cur,dp[x]). 每次询问的时候答案就是min(cur,dp[x]). 如果觉得很神