最少的硬币数量组合出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 ...
随机推荐
- 实战:ADFS3.0单点登录系列-集成SharePoint
这是本系列第四篇了,终于轮到SharePoint上场了,但是本文不会过多讲解SharePoint安装等话题,而是直入主题,讲解如何进行配置,让其于ADFS配合完成SSO的工作. 注意:本文使用的Sha ...
- office密匙
office 2010 VYBBJ-TRJPB-QFQRF-QFT4D-H3GVB 6QFDX-PYH2G-PPYFD-C7RJM-BBKQ8 BDD3G-XM7FB-BD2HM-YK63V-VQFD ...
- IOS 九宫图解锁(封装)
NJLockView.h /.m @class NJLockView; @protocol NJLockViewDelegate <NSObject> - (void)lockViewDi ...
- 【BZOJ2120】数颜色(带修莫队)
点此看题面 大致题意:告诉你\(n\)只蜡笔的颜色,有两种操作:第一种操作将第\(x\)只蜡笔颜色改成\(y\),第二种操作询问区间\([l,r]\)内有多少种颜色的蜡笔. 考虑普通莫队 这题目第一眼 ...
- Java环境变量搭建(Linux环境)
1. 下载解压JDK压缩包 例如:解压到 /opt/jdk1.7.0_80 下 2. 添加环境变量到 /etc/profile 文件中 vi /etc/profile 在文件末尾追加如下内容: exp ...
- 客户端(springmvc)调用netty构建的nio服务端,获得响应后返回页面(同步响应)
后面考虑通过netty做一个真正意义的简约版RPC框架,今天先尝试通过正常调用逻辑调用netty构建的nio服务端并同步获得返回信息.为后面做铺垫 服务端实现 我们先完成服务端的逻辑,逻辑很简单,把客 ...
- 如何让图片相对于上层DIV始终保持水平、垂直都居中
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- CSVDE
csvde -f C:\export_OrganizationalUnit.csv -r '(objectClass=organizationalUnit)' -l 'displayName,prox ...
- c++ 中十进制 八进制 十六进制 二进制转换 最简方法
#include<iostream> using namespace std; int main() { int i; cin>>dec>>i; //cin> ...
- C# 界面跳转-登陆之后跳转至主窗口
在登陆按钮验证成功之后可以将会话结果改为OK //验证通过之后将对话结果设置为OK(之后会载入主界面) this.DialogResult = DialogResult.OK; this.Dispos ...