最少的硬币数量组合出1到m之间的任意面值(贪心算法)
题目描述:
你有n种不同面值的硬币,每种面值的硬币都有无限多个,为了方便购物,你希望带尽量少的硬币,并且要能组合出 1 到 m 之间(包含1和m)的所有面值。
输入描述:
第一行包含两个整数:m ,n(1 ≤ n ≤ 100,1 ≤ m ≤ 109),意义如题目描述。接下来的 n 行,每行一个整数,第 i + 1 行的整数表示第 i 种硬币的面值。
输出描述:
输出一个整数,表示最少需要携带的硬币数量,再输出以空格为分隔的一串整数,表示对应的硬币面值。如果无解,则输出-1。
示例:
输入:
20 4
1
2
5
10
输出:
5
1 2 2 5 10
分析:
首先,硬币面值必须有1,否则无法组合1(其实只要有了1,便可以组合出任意面值)。
用sum表示当前能组合的最大面值,即可以组合1~sum的所有面值。
当sum ≥ m时,就停止组合。
当sum < m时,要继续组合,即组合sum + 1,我们事先把不同面值的硬币排序,从这里面找到满足 ≤ sum + 1的最大面值的硬币,为什么需要是最大面值呢,因为这样才能保证硬币数最少。假设找到的硬币面值是coin[i],此时,更新sum += a[i],并将硬币数量+1。以上面的示例为例,当sum = 4时,下一次要凑5,我们在面值数组里找到了满足条件的5,因为sum = 4表示能凑齐1~4,现在有了面值为5的硬币,又可以组合出5~9,总共可以组合出1~9,所以我们更新sum = 4 + 5 = 9,表示现在可以组合1~9。按此思想,如此循环下去……,直到sum ≥ m。
显然是用贪心算法来解决问题了。
代码:
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std; int main()
{
int m = ; // 要组合出1~m的任意面值
int n = ; // 不同面值的硬币数量
vector<int> coin; // 不同面值的硬币
int sum = ; // 当前能组合出的最大面值
int count = ; // 当前需要的硬币数量
vector<int> trace; // 当前需要的硬币面值
cin >> m >> n;
for (int i = ; i < n; i++){
int temp;
cin >> temp;
coin.push_back(temp);
}
sort(coin.begin(), coin.end()); //硬币按面值升序排列
// 如果没有面值为1的硬币,则无解
if (coin[] != ){
cout << - << endl;
system("pause");
return ;
}
while (true){
// 如果可以组合出大于等于m的面值,则输出count
if (sum >= m){
cout << count << endl;
for (auto &i : trace)
cout << i << "\t";
system("pause");
return ;
}
// 找满足<= sum + 1的最大面值的硬币
for (int i = n - ; i >= ; i--){
if (coin[i] <= sum + ){
trace.push_back(coin[i]); // 保存需要的硬币面值
sum += coin[i]; // 更新sum
count++; // 更新count
break; // 跳出并判断此时的sum是否>=m
}
}
}
return ;
}
测试:
最少的硬币数量组合出1到m之间的任意面值(贪心算法)的更多相关文章
- 【BZOJ4830】[HNOI2017]抛硬币(组合计数,拓展卢卡斯定理)
[BZOJ4830][HNOI2017]抛硬币(组合计数,拓展卢卡斯定理) 题面 BZOJ 洛谷 题解 暴力是啥? 枚举\(A\)的次数和\(B\)的次数,然后直接组合数算就好了:\(\display ...
- d029: 求出2-100之间的所有质数(素数)
内容: 求出2-100之间的所有质数(素数) 输入说明: 无 输出说明: 一行一个素数 /* 质数又称素数.指在一个大于1的自然数中,除了1和此整数自身外,不能被其他自然数(不包括0)整除的数. */ ...
- 组合优化学习笔记<之>从贪心算法到子集系统再到拟阵
贪心算法是用的比较多的一种优化算法,因为它过程简洁优美,而且结果有效.有些优化问题如最大权森林(MWF)是可以用贪心问题求解的,由于最小支撑树(MST)问题与MWF是等价的,所以MST也是可以用贪心算 ...
- MTK Android Git提取出两个版本之间的差异文件并打包
git提取出两个版本之间的差异文件并打包 首先你得知道版本之间的commit id git log –pretty=oneline $ git log --pretty=oneline 1 差异文件并 ...
- java中请给出例子程序:找出n到m之间的质数。
9.1 找出100到200之间的质数. public class Test { public static void main(String[] args){ for (in ...
- SQL 谜题(硬币的组合)
问题:早在ITPUB中看过有个SQL高手,喜欢出谜题,以下是一个谜题.我试用SQL SERVER解决此问题. 用1分,5分,10分,25分,50分硬币凑成一元,总共有几种组合办法? SELECT'1* ...
- 洛谷P2851 [USACO06DEC]最少的硬币The Fewest Coins(完全背包+多重背包)
题目描述 Farmer John has gone to town to buy some farm supplies. Being a very efficient man, he always p ...
- 322. Coin Change选取最少的硬币凑整-背包问题变形
[抄题]: You are given coins of different denominations and a total amount of money amount. Write a fun ...
- 用最少的JS代码写出贪吃蛇游戏---迷你版
游戏进行页面展示 GAME OVER 页面展示 代码如下: <!doctype html> <html> <body> <canvas id=&q ...
随机推荐
- C# 字符串转组件名、变量名
字符串转组件名 (Controls["button1"] as Button).Text = "Hello";//单独组件 (Controls[].Contro ...
- mongodb 入坑
一.安装mongodb https://www.mongodb.com/ 官网下载合适的版本,安装在C或者D盘,我选择的是默认路径C:\Program Files\MongoDB\Server\3.4 ...
- 关于添加IBDesignable实时building很卡问题的解决
公共库加了@IBDesignable,可以实时预览图标 但是有个问题,每次打开XIB的时候都会Building,会造成电脑会很卡 有个解决方法,在xcode的Editor下拉框取消auto refre ...
- World Wind Java开发之十二——加载粗制三维模型(ExtrudedPolygon)(转)
ww可以根据DLG图批量生成假三维模型,这对于小区等特征相似的建筑物模型的构建是非常有用的.下面来看如何一步步实现假三维模型的加载: 1.Shp文件的制作 首先在arcmap下数字化几个建筑物,并新建 ...
- AOJ 558 Cheese(bfs)
题意:网格图,老鼠吃奶酪,吃完奶酪体力值会增加,只能吃硬度不大于体力值的,问最小步数. 思路:按硬度从小到大的吃起,依次求最短路. 我用曼哈顿距离估价的A*,和普通bfs的time没区别啊,还把优先级 ...
- UVA Live Archive 4394 String painter(区间dp)
区间dp,两个str一起考虑很难转移. 看了别人题解以后才知道是做两次dp. dp1.str1最坏情况下和str2完全不相同,相当于从空白串开始刷. 对于一个区间,有两种刷法,一起刷,或者分开来刷. ...
- 【转】IOS开发网络篇之──ASIHTTPRequest详解
ASIHTTPRequest 详解, http 请求终结者 版权归旺财勇士所有〜转载需声名〜 原贴地地址:http://wiki.magiche.net/pages/viewpage.action?p ...
- 2018.7.1 css项目之模仿满屋花首页css+idv布局实现
可以分开写 <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF ...
- solr 近实时搜索
摘要: Solr的近实时搜索NRT(Near Real Time Searching)意味着文档可以在索引以后马上可以被查询到. Solr不会因为本次提交而阻塞更新操作,不会等待后台合并操作(merg ...
- 人脸验证算法Joint Bayesian详解及实现(Python版)
人脸验证算法Joint Bayesian详解及实现(Python版) Tags: JointBayesian DeepLearning Python 本博客仅为作者记录笔记之用,不免有很多细节不对之处 ...