• D. Digits DP


    D. Digits DP

    题目大意:

    你有 (n) 张卡片,每张卡片上有一个数字,你可以选择一个非空的集合,这些卡片上的数字相乘最后得到的十进制数的个位上的数字是 (d) ,问满足要求的最大的数

    题解:

    很容易想到的是 (DP) 的定义:(dp[i][j]) 表示前 (i) 个数,个位上的数是 (j) 的最大值。

    这个题目的坑点在于如果直接乘起来的话会爆 (long\,long)

    所以需要用对数函数转化成加法,然后就只要注意一下这个求路径的方法就可以了。

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn = 1e5 + 10;
    double dp[maxn][11];
    int f[maxn][11],pre[maxn][11];
    vector<int>ans;
    ll a[maxn];
    int main() {
        int n, d;
        scanf("%d%d", &n, &d);
        memset(f,-1,sizeof(f));
        f[0][1] = 0;
        for(int i=1;i<=n;i++) {
            scanf("%lld", &a[i]);
            for (int j = 0; j <= 9; j++) {
                if (f[i - 1][j] != -1) {
                    int k = a[i] * j % 10;
                    double cur = dp[i - 1][j] + log(1.0 * a[i]);
                    if (cur > dp[i][k]) {
                        f[i][k] = 1, dp[i][k] = cur, pre[i][k] = j;
                    }
                    if (f[i][j] == -1 || dp[i - 1][j] > dp[i][j]) {
                        dp[i][j] = dp[i - 1][j], f[i][j] = 0, pre[i][j] = j;
                    }
                }
            }
        }
        if(f[n][d]==-1){
            printf("-1
    ");
            return 0;
        }
        int now = n,pos = d;
        while(now>=1) {
            if (f[now][pos]) {
                ans.push_back(a[now]);
                pos = pre[now][pos];
            }
            now--;
        }
        if(!ans.size()) printf("-1
    ");
        else {
            sort(ans.begin(),ans.end());
            printf("%d
    ",ans.size());
            for(auto x:ans) printf("%d ",x);
            printf("
    ");
        }
    }
    
  • 相关阅读:
    mysql时间日期的加、减
    IDEA 下的svn检出maven代码
    IDEA中如何显示和关闭工具栏、目录栏
    Idea集成使用SVN教程
    Python PEP8 代码规范常见问题及解决方法
    Word文档中手写签名操作说明
    19.名称空间和作用域
    18.函数的参数
    17.文件处理
    16.字符编码
  • 原文地址:https://www.cnblogs.com/EchoZQN/p/14635195.html
Copyright © 2020-2023  润新知