• 【动态规划】Round Subset


    CF837D. 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 possible.

    Input

    The first line contains two integer numbers n and k (1 ≤ n ≤ 200, 1 ≤ k ≤ n).

    The second line contains n space-separated integer numbers a1, a2, ..., an (1 ≤ ai ≤ 1018).

    Output

    Print maximal roundness of product of the chosen subset of length k.

    Examples
    input
    3 2
    50 4 20
    output
    3
    input
    5 3
    15 16 3 25 9
    output
    3
    input
    3 3
    9 77 13
    output
    0
    Note

    In the first example there are 3 subsets of 2 numbers. [50, 4] has product 200 withroundness 2, [4, 20] — product 80, roundness 1, [50, 20] — product 1000, roundness 3.

    In the second example subset [15, 16, 25] has product 6000, roundness 3.

    In the third example all subsets has product with roundness 0.

    题目大意:从N个数中选出M个数使得这M个数的乘积后的0最多。

    试题分析:不难发现,构成一个0的条件是2*5,那么对于每一个数字我们求出它的质因数分解中有多少2多少5

         dp[i][j]表示选i个数其中有j个2最多有多少个5

         那么dp[i][j]=max(dp[i-1][j-t2]+t5);

         其中t2为质因数分解中2的个数,t5为质因数分解中5的个数。

    代码:

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<vector>
    #include<queue>
    #include<cmath>
    #include<stack>
    #include<algorithm>
    using namespace std;
    
    inline long long read(){
    	long long x=0,f=1;char c=getchar();
    	for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
    	for(;isdigit(c);c=getchar()) x=x*10+c-'0';
    	return x*f;
    }
    const int MAXN=1001;
    const int INF=0x3f3f3f;
    const int n2=206*64; 
    int MAX=-INF;
    int N,M;
    int dp[MAXN][n2+1];
    long long a[MAXN];
    int ans;
    
    int main(){
    	N=read(),M=read();
    	for(int i=1;i<=N;i++) a[i]=read();
    	for(int i=0;i<=M;i++)
    		for(int j=0;j<n2;j++) dp[i][j]=-INF;
    	dp[0][0]=0;
    	for(int i=1;i<=N;i++){
    		long long x=a[i],x2=a[i];
    		int T2=0,T5=0;
    		while(x%2==0) x/=2,T2++;
    		while(x2%5==0) x2/=5,T5++;
    		for(int k=M;k>=1;k--)
    		    for(int j=T2;j<n2;j++)
    		    	dp[k][j]=max(dp[k-1][j-T2]+T5,dp[k][j]);
    	}
    	ans=0; 
    	for(int i=1;i<n2;i++)
    		ans=max(ans,min(dp[M][i],i));
    	cout<<ans<<endl;
    }
  • 相关阅读:
    JSP课程设计:宿舍管理系统(附源码)
    【博客模板页】从此不再为写博客头疼 (ノ ̄▽ ̄)~(ノ ̄▽ ̄)~(ノ ̄▽ ̄)~
    个人自定义的快捷键
    碎知识点收藏栏 [逆序时间排版]
    JavaSE (46)
    《Java8实战》05
    Python04
    【BUG11】
    三、如何科学地做到:算法竞赛从入门到放弃/算法竞赛从了解入坑到快速放弃指南?
    二、如何科学地在面试时踩雷?
  • 原文地址:https://www.cnblogs.com/wxjor/p/7287427.html
Copyright © 2020-2023  润新知