Codeforces 837 D Round Subset

来源:互联网 发布:union all 不同数据库 编辑:程序博客网 时间:2024/06/01 20:47

题目地址
题意:给你个序列,选择k个数,求乘积的后缀零最多
思路:因为0是由2和5的乘积组成的,然后经别人提醒可以用dp去写,其实就可以转变为01背包的问题(注释比较详细)
PS:为什么用5来做0的标准,因为2比较容易找到(我是这样觉得的)

#include <iostream>#include <cstring>#include <string>#include <queue>#include <vector>#include <map>#include <set>#include <stack>#include <cmath>#include <cstdio>#include <algorithm>#include <iomanip>#define N 210#define M 13000#define LL long long#define inf 0x3f3f3f3f3f3f3f3f#define lson l,mid,ans<<1#define rson mid+1,r,ans<<1|1#define getMid (l+r)>>1#define movel ans<<1#define mover ans<<1|1using namespace std;const LL mod = 1e9 + 7;const double eps = 1e-9;struct node {    int num5, num2;}num[N];LL dp[N][M];//dp[i][j],i代表的是第i个数字,j代表的是,dp记录的是能构成0的个数int main(){    cin.sync_with_stdio(false);    LL n, k;    while (cin >> n >> kk){        for (int i = 0; i<n; i++){            LL nums;            cin >> nums;            num[i].num5 = 0, num[i].num2 = 0;            while (nums % 5 == 0) {                num[i].num5++, nums /= 5;            }            while (nums % 2 == 0) {                num[i].num2++, nums /= 2;            }        }        memset(dp, -inf, sizeof(dp));        dp[0][0] = 0;        for (int i = 0; i<n; i++){//当前选择的数字            for (int j = kk; j >= 1; j--){//选择放在第j个拿                for (int k = M - 1; k >= 0; k--){//当前2的个数                    if (k - num[i].num2 >= 0)                        dp[j][k] = max(dp[j][k], dp[j - 1][k - num[i].num2] + num[i].num5);                }            }        }        LL ans = 0;        for (LL i = 0; i<M; i++){            ans = max(ans, min(i, dp[kk][i]));        }        cout << ans << endl;    }    return 0;}
原创粉丝点击