Codeforces 837D

 先算出每个数的pop1(twonum),pop(fivenum)然后DP ans[i][j]表示选i个数有j个2时最多有多少个5

转移方程是

        for(int j=k;j>=1;j--)
        {
        for(int w=pop1;w<5000;w++)
        {
        ans[j][w]=max(ans[j][w],ans[j-1][w-pop1]+pop);
        }
        }

AC程序:

#include <bits/stdc++.h>
#include <cstring>
#include <iostream>
#include <algorithm>
#include<queue>
#define EPS 1.0e-9
#define PI acos(-1.0)
#define INF 30000000
#define MOD 1000000007
#define mem(a,b) memset((a),b,sizeof(a))
#define TS printf("!!!
")
#define pb push_back
#define pai pair<int,int>
//using ll = long long;
//using ull= unsigned long long;
//std::ios::sync_with_stdio(false);
using namespace std;
//priority_queue<int,vector<int>,greater<int>> que;
typedef long long ll;
typedef unsigned long long ull;
const int maxn=1005;
struct num
{
  int two;
  int five;
}number[205];
ll ans[205][5001];
int main()
{
        mem(ans,-1);
        ans[0][0]=0;
    int n;
    int k;
    cin >> n >> k;
    int now;
    int pop,pop1;
    num temp;
    for(int i=1;i<=n;i++)
        {
        pop=pop1=0;
        cin >> now;
        while(now&&now%5==0)
        {
        pop++;
        now/=5;
        }
        while(now&&now%2==0)
        {
        pop1++;
        now/=2;
        }
        for(int j=k;j>=1;j--)
        {
        for(int w=pop1;w<5000;w++)
        {
        ans[j][w]=max(ans[j][w],ans[j-1][w-pop1]+pop);
        }
        }
        }
        ll anser=0;
        for(ll i=1;i<=5000;i++)
        anser=max(anser,min(i,ans[k][i]));
        cout<<anser<<endl;
    return 0;
}
原文地址:https://www.cnblogs.com/Aragaki/p/7350380.html