美文网首页
PATA1068 硬币问题

PATA1068 硬币问题

作者: crishawy | 来源:发表于2019-04-25 21:37 被阅读0次

链接:https://pintia.cn/problem-sets/994805342720868352/problems/994805402305150976

程序代码:

#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
/*
    该题需要好好掌握思想,如何将恰好问题转换为背包问题
    以及倒序追踪法,求的序列结果
*/
using namespace std;

const int maxn = 10010;
const int maxm = 110;
int w[maxn],dp[maxm];
bool choice[maxn][maxm];
bool flag[maxn];

int cmp(int a,int b){
    return a > b;
}

int main(int argc, char const *argv[])
{
    int n,M;
    scanf("%d%d",&n,&M);
    for(int i=1;i<=n;i++)
        scanf("%d",&w[i]);
    //为了保证输出结果按字典顺序排列,将硬币价格倒序
    sort(w + 1,w + n + 1,cmp);
    //初始阶段
    for(int v=0;v<=M;v++)
        dp[v] = 0;
    //n个阶段
    for(int i=1;i<=n;i++){
        //逆序dp
        for(int v=M;v>=w[i];v--){
            //注意加上等号:因为需按字典顺序向下更新
            if(dp[v] <= dp[v-w[i]] + w[i]){
                dp[v] = dp[v-w[i]] + w[i];
                choice[i][v] = true;
            }else{
                choice[i][v] = false;
            }
        }
    }
    //找到最后一阶段中最大的dp
    int v = 0;
    for(int i=1;i<=M;i++){
        if(dp[i] > dp[v])
            v = i;
    }
    if(dp[v] != M){
        //不能恰好组成M
        printf("No Solution\n");
        return 0;
    }
    //倒序追踪法寻找完整序列
    // printf("max:%d\n",dp[v] );
    std::vector<int> result;
    for(int i=n;i>=1;i--){
        if(choice[i][v] == true){
            // flag[i] = true;
            //更新i-1阶段的状态
            result.push_back(w[i]);
            v = v - w[i];
        }
    }
    for(int i=0;i<result.size();i++){
        printf("%d",result[i] );
        if(i != result.size() - 1)
            printf(" ");
    }
    return 0 ;
    //
}

相关文章

  • PATA1068 硬币问题

    链接:https://pintia.cn/problem-sets/994805342720868352/prob...

  • 硬币问题

  • 函数式编程思想

    换硬币问题 问题就是动态规划里面的换硬币问题。所以函数式编程的关键和动态规划问题一样:递归关系式。换硬币问题发现他...

  • 最小硬币找零问题

    最小硬币找零问题是硬币找零问题的一个变种。硬币找零问题是给出要找零的钱数,以及可以用的硬币面额d1...dn及其数...

  • 抛硬币问题

    抛硬币是概率论和随机过程中的经典实验。假设我们抛掷一枚均匀硬币,直到连续出现k次反面。求抛掷次数和出现反面次数的期...

  • 硬币组合问题

    问题描述 有 N 枚硬币,面值分别是 a1,a2,..ai,..aN,问可不可以凑成 M? 思路分析 这个题,直接...

  • 翻硬币问题

    题目 总共有n枚硬币均正面朝上,规则规定每次只能将其中p枚硬币翻面(1≤p≤n)。问最少需要多少次操作才能将所有硬...

  • 最少硬币问题

    描述:假设你有面值为1块、2块、5块的硬币,用尽可能少的硬币凑n块钱。 贪婪算法和动态规划的问题 此题的贪婪算法很...

  • 用Swift的函数式编程解决硬币问题

    用Swift的函数式编程解决硬币问题 用Swift的函数式编程解决硬币问题

  • [源码和文档分享]基于JAVA的实现的16个硬币问题

    版本1 参考9枚硬币反面问题的模型,建立16枚硬币反面问题的模型,以及其他结构的模型。 版本2 参考9枚硬币反面问...

网友评论

      本文标题:PATA1068 硬币问题

      本文链接:https://www.haomeiwen.com/subject/cxvtnqtx.html