题目如下:

Eva loves to collect coins from all over the universe, including some other planets like Mars. One day she visited a universal shopping mall which could accept all kinds of coins as payments. However, there was a special requirement of the payment: for each bill, she must pay the exact amount. Since she has as many as 104 coins with her, she definitely needs your help. You are supposed to tell her, for any given amount of money, whether or not she can find some coins to pay for it.

Input Specification:

Each input file contains one test case. For each case, the first line contains 2 positive numbers: N (<=104, the total number of coins) and M(<=102, the amount of money Eva has to pay). The second line contains N face values of the coins, which are all positive numbers. All the numbers in a line are separated by a space.

Output Specification:

For each test case, print in one line the face values V1 <= V2 <= ... <= Vk such that V1 + V2 + ... + Vk = M. All the numbers must be separated by a space, and there must be no extra space at the end of the line. If such a solution is not unique, output the smallest sequence. If there is no solution, output "No Solution" instead.

Note: sequence {A[1], A[2], ...} is said to be "smaller" than sequence {B[1], B[2], ...} if there exists k >= 1 such that A[i]=B[i] for all i < k, and A[k] < B[k].

Sample Input 1:

8 9
5 9 8 7 2 3 4 1

Sample Output 1:

1 3 5

Sample Input 2:

4 8
7 2 4 3

Sample Output 2:

No Solution

题目要求从一系列硬币中找出最小的、满足给定面值和的硬币序列,这属于典型的背包问题,问题的难点在于输出最小序列。

【如何找到这样的序列】

我们设f(i,j)表示从前i个硬币中选出的面值不大于j的最大的面值和,设硬币序列中第i个硬币的面值为c[i],则f(i,j)的计算可以分为两种情况递推考虑:

每个硬币都有放入和不放入两种情况。

①放入第i个硬币,即f(i-1,j - c[i]) + c[i]。

②不放入第i个硬币,即f(i-1,j)。

要保证面值最大,应该选择二者中的较大者,因此递推式如下:

因此我们只要从i=1~N,分别解决j=1~M的问题,便可以得到不超过M的最大面值,通过判断f(N,M),如果它=M,说明能够找到这样的序列,否则说明找不到,因为它是不超过M的,从所有硬币中能组合出的最大的和。

【如何使序列最小】

接下来我们解决序列最小的问题,我们这样考虑,每当加入一个c[i],序列中就会多一个元素,如果我们让硬币按照降序排列,这样每一次加入c[i],都相当于加入了一个更小的序列头,例如现在的序列是{5,3,2},因为是降序,c[i]≤2,因此只要加入c[i],序列会编程{5,3,2,c[i]},这个序列必定变小,因此我们应该记录下所有加入c[i]时的下标,最后根据这些下标回溯,即可得到最小的序列。

以下代码来着tiantangrenjian,感谢他提供的解法;关于最小序列的找法,学习自gzxcyy,感谢他的详尽分析。

#include <iostream>
#include <fstream>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;#define MAXTOTAL    10001
#define MAXAMOUNT   101int f[MAXTOTAL][MAXAMOUNT];          //f[n][m]表示 前n个数中 得出的 最接近m 的值
bool has[MAXTOTAL][MAXAMOUNT];      //has[n][m]表示在前n个数中得出最接近m的值时 是否用到c[n]
int* c = NULL;int calcClosestSum(int n,int m)
{memset(f,0,sizeof(int)*MAXTOTAL*MAXAMOUNT);memset(has,false,sizeof(bool)*MAXTOTAL*MAXAMOUNT);int i,j;int sec; // 表示放入c[i]后的值for(i=1;i<n+1;i++){for(j=1;j<=m;j++){if(j-c[i]<0) sec=0; // 如果不满足小于等于j,则说明放入后是非法值,可以设其为0,表示面值无效。else sec = f[i-1][j-c[i]]+c[i]; // 正常情况下计算放入c[i]的值。if(f[i-1][j] > sec){f[i][j]=f[i-1][j];}else{f[i][j]=sec;has[i][j]=true;      //用到c[i]了 设has[i][j]为true}}}return f[n][m];
}bool cmp(const int& A,const int& B)
{return A>B;
}int main()
{int n,m;cin>>n>>m;c = new int[n+1];memset(c,0,sizeof(int)*(n+1));int i;for(i=0;i<n;i++){cin>>c[i+1];}sort(&c[1],&c[n+1],cmp);     //从大到小排序int res = calcClosestSum(n,m);if(res==m)                 //有解{vector<int> v;while(m){while(!has[n][m])n--;v.push_back(c[n]);m = m - c[n];n--;}for(i=0;i<v.size()-1;i++)cout<<v[i]<<' ';cout<<v[i]<<endl;}else                     //无解cout<<"No Solution"<<endl;return 0;
}

转载于:https://www.cnblogs.com/aiwz/p/6154086.html

1068. Find More Coins (30)相关推荐

  1. PAT甲级1068 Find More Coins (30 分):[C++题解]DP、背包问题、dp输出方案

    文章目录 题目分析 题目链接 题目分析 来源:acwing 分析:m是背包容量,a1,a2,....,ana_1,a_2,....,a_na1​,a2​,....,an​是n个物品,第i个物品的体积是 ...

  2. 1068 Find More Coins (30分)

    文章目录 1 题目 2 解析 2.1 题意 2.2 思路 3 参考代码 1 题目 1068 Find More Coins (30分) Eva loves to collect coins from ...

  3. 1068 Find More Coins (30 分)【难度: 难 / 知识点:01背包问题 + 找路径】

    https://pintia.cn/problem-sets/994805342720868352/problems/994805402305150976 f[i][j] 表示的是从前i个物品种选,体 ...

  4. PAT甲级 1068

    文章目录 1068 Find More Coins 1.回溯法 2.动态规划 1)f [m][n]的求解 2)进一步得缩小空间复杂度 2)是否有解,以及求取最小解 参考链接: 1068 Find Mo ...

  5. PAT (Advanced Level) Practice 题解代码 - II (1051-1100)

    PAT PAT (Advanced Level) Practice - II(1051-1100) -------------------------------------------------- ...

  6. 刷PAT甲级的各题思路、细节以及遇到的问题记录

    1001 A+B Format (20分) 因为一定会用到字符串,而string非常好用,但是用的时候一定要注意不能越界访问,否则会在运行时出现abort() has been called. 100 ...

  7. PAT甲级真题目录(按题型整理)(转自柳神)

    转载自:https://www.liuchuo.net/archives/2502?tdsourcetag=s_pcqq_aiomsg 最短路径 1003. Emergency (25)-PAT甲级真 ...

  8. PAT甲级训练合集(1-70)

    本章题解跳转 考点 P1001 数字的数组表示和处理 P1002 多项式的数组表示和处理 P1003 深度优先搜素 P1004 深度优先搜素 P1005 哈希表 P1006 P1007 数组子区间求和 ...

  9. 【PAT甲级真题整理三】1061~1090

    目录 1061 Dating(20)字符串处理 1062 Talent and Virtue(25)排序 1063 Set Similarity(25)set的使用 1064 Complete Bin ...

最新文章

  1. [置顶] 单键模式的C++描述
  2. 【译】Swift算法俱乐部-查找最大/最小值
  3. 助力AI腾飞,深度学习走向何方?
  4. 开源软件5大常见问题及解决方法
  5. saber软件安装后怎么打开_教程:新《Beat Saber》mod安装工具已推出
  6. linux apr文件解压失败,Linux安装apache服务器遇到的问题
  7. 算法证明_CFR+算法证明过程
  8. bagging算法_Bagging/Boosting傻傻分不清?来一探究竟吧~
  9. java 关于集合的笔试题_Java集合面试题(一)
  10. php插件改名,自制functions.php文件or插件,防止升级或更换主题时被替换
  11. atom之插件安装及相关
  12. 「3D手指血管扫描」一套无法复制的生物识别系统
  13. 搜狗输入法 linux 源码,1.下载搜狗输入法for linux源码包:
  14. 自动安装L2tp的脚本
  15. 博客前端模板源码(力荐)
  16. 短期出差北京个人所见所闻所感
  17. MongoDB5.0安装总结(简单)
  18. matlab适应度函数为什么有2个输出,基于遗传算法的LQR优化问题,适应度函数总是报错。...
  19. 概率论05 - 随机变量及其分布函数
  20. JDK19都出来了~是时候梳理清楚JDK的各个版本的特性了【JDK17特性讲解】

热门文章

  1. javascript类功能代码集
  2. 填表法解“银行家算法”问题
  3. python成绩管理系统设计 gui csdn_用golang简单编写学生信息管理系统
  4. SDP 软件定义边界
  5. java中输出进程的映像名称,怎么修改tomcat进程的名称(windows)
  6. 转自云风blog:三国志战略版服务器卡顿问题
  7. node mysql 查询_Node.js使用mysql进行查询详解
  8. css文字在图片下方_【HTML+CSS】文字和图片保持同一水平线的三种方式
  9. mysql5.5数据备份_MySql5.5备份和还原
  10. 三、MySql 数据类型