zoukankan      html  css  js  c++  java
  • HihoCoder1706 : 末尾有最多0的乘积(还不错的DP)

    描述

    给定N个正整数A1, A2, ... AN。  

    小Hi希望你能从中选出M个整数,使得它们的乘积末尾有最多的0。

    输入

    第一行包含两个个整数N和M。  

    第二行包含N个整数A1, A2, ... AN。  

    对于30%的数据,1 ≤ M ≤ N ≤ 12  

    对于100%的数据,1 ≤ M ≤ N ≤ 100  1 ≤ Ai ≤ 1000000000

    输出

    末尾最多的0的个数

    样例输入

    4 2  
    8 25 30 40

    样例输出

    3

    DP[N][M][X]表示前面N个数选择M个数有X个5时,最多有多少个2。

    比赛的时候一直在想4维的做法,最后60分,GG了。想来还是背包类DP做少了。

    #include<cmath>
    #include<cstring>
    #include<memory.h>
    #include<bitset>
    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    const int maxn=110;
    int t[maxn],f[maxn],ans;
    int N,M;
    int dp[102][102][902];
    int main()
    {
        int x,y,i,j,k,sum=0;
        scanf("%d%d",&N,&M);
        for(i=1;i<=N;i++){
            scanf("%d",&x);y=x;
            while(y%5==0) {
                t[i]++; y/=5;
                sum++;
            }
            while(x%2==0){
                f[i]++;x/=2;
            }
        }
        memset(dp,-1,sizeof(dp));
        dp[0][0][0]=0;
        sum=min(sum,900);
        for(i=1;i<=N;i++) 
         for(j=0;j<=min(i,M);j++)
          for(k=0;k<=sum;k++){
             dp[i][j][k]=dp[i-1][j][k];
             if(k>=t[i]&&j>=1&&dp[i-1][j-1][k-t[i]]!=-1) dp[i][j][k]=max(dp[i][j][k],dp[i-1][j-1][k-t[i]]+f[i]); 
        }
        for(i=1;i<=sum;i++) ans=max(ans,min(dp[N][M][i],i));
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    Hbase表的管理
    Hbase指定规则扫描表
    vim配置
    caogao
    go on shell
    实习总结
    shell 脚本
    hadoop实战
    awk使用
    java reflect
  • 原文地址:https://www.cnblogs.com/hua-dong/p/8544756.html
Copyright © 2011-2022 走看看