题目描述:

你有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之间的任意面值(贪心算法)的更多相关文章

  1. 【BZOJ4830】[HNOI2017]抛硬币(组合计数,拓展卢卡斯定理)

    [BZOJ4830][HNOI2017]抛硬币(组合计数,拓展卢卡斯定理) 题面 BZOJ 洛谷 题解 暴力是啥? 枚举\(A\)的次数和\(B\)的次数,然后直接组合数算就好了:\(\display ...

  2. d029: 求出2-100之间的所有质数(素数)

    内容: 求出2-100之间的所有质数(素数) 输入说明: 无 输出说明: 一行一个素数 /* 质数又称素数.指在一个大于1的自然数中,除了1和此整数自身外,不能被其他自然数(不包括0)整除的数. */ ...

  3. 组合优化学习笔记<之>从贪心算法到子集系统再到拟阵

    贪心算法是用的比较多的一种优化算法,因为它过程简洁优美,而且结果有效.有些优化问题如最大权森林(MWF)是可以用贪心问题求解的,由于最小支撑树(MST)问题与MWF是等价的,所以MST也是可以用贪心算 ...

  4. MTK Android Git提取出两个版本之间的差异文件并打包

    git提取出两个版本之间的差异文件并打包 首先你得知道版本之间的commit id git log –pretty=oneline $ git log --pretty=oneline 1 差异文件并 ...

  5. java中请给出例子程序:找出n到m之间的质数。

    9.1 找出100到200之间的质数.  public class Test {     public static void main(String[] args){         for (in ...

  6. SQL 谜题(硬币的组合)

    问题:早在ITPUB中看过有个SQL高手,喜欢出谜题,以下是一个谜题.我试用SQL SERVER解决此问题. 用1分,5分,10分,25分,50分硬币凑成一元,总共有几种组合办法? SELECT'1* ...

  7. 洛谷P2851 [USACO06DEC]最少的硬币The Fewest Coins(完全背包+多重背包)

    题目描述 Farmer John has gone to town to buy some farm supplies. Being a very efficient man, he always p ...

  8. 322. Coin Change选取最少的硬币凑整-背包问题变形

    [抄题]: You are given coins of different denominations and a total amount of money amount. Write a fun ...

  9. 用最少的JS代码写出贪吃蛇游戏---迷你版

    游戏进行页面展示 GAME  OVER 页面展示  代码如下: <!doctype html> <html>   <body>   <canvas id=&q ...

随机推荐

  1. 实战:ADFS3.0单点登录系列-集成SharePoint

    这是本系列第四篇了,终于轮到SharePoint上场了,但是本文不会过多讲解SharePoint安装等话题,而是直入主题,讲解如何进行配置,让其于ADFS配合完成SSO的工作. 注意:本文使用的Sha ...

  2. office密匙

    office 2010 VYBBJ-TRJPB-QFQRF-QFT4D-H3GVB 6QFDX-PYH2G-PPYFD-C7RJM-BBKQ8 BDD3G-XM7FB-BD2HM-YK63V-VQFD ...

  3. IOS 九宫图解锁(封装)

    NJLockView.h /.m @class NJLockView; @protocol NJLockViewDelegate <NSObject> - (void)lockViewDi ...

  4. 【BZOJ2120】数颜色(带修莫队)

    点此看题面 大致题意:告诉你\(n\)只蜡笔的颜色,有两种操作:第一种操作将第\(x\)只蜡笔颜色改成\(y\),第二种操作询问区间\([l,r]\)内有多少种颜色的蜡笔. 考虑普通莫队 这题目第一眼 ...

  5. Java环境变量搭建(Linux环境)

    1. 下载解压JDK压缩包 例如:解压到 /opt/jdk1.7.0_80 下 2. 添加环境变量到 /etc/profile 文件中 vi /etc/profile 在文件末尾追加如下内容: exp ...

  6. 客户端(springmvc)调用netty构建的nio服务端,获得响应后返回页面(同步响应)

    后面考虑通过netty做一个真正意义的简约版RPC框架,今天先尝试通过正常调用逻辑调用netty构建的nio服务端并同步获得返回信息.为后面做铺垫 服务端实现 我们先完成服务端的逻辑,逻辑很简单,把客 ...

  7. 如何让图片相对于上层DIV始终保持水平、垂直都居中

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  8. CSVDE

    csvde -f C:\export_OrganizationalUnit.csv -r '(objectClass=organizationalUnit)' -l 'displayName,prox ...

  9. c++ 中十进制 八进制 十六进制 二进制转换 最简方法

    #include<iostream> using namespace std; int main() { int i; cin>>dec>>i; //cin> ...

  10. C# 界面跳转-登陆之后跳转至主窗口

    在登陆按钮验证成功之后可以将会话结果改为OK //验证通过之后将对话结果设置为OK(之后会载入主界面) this.DialogResult = DialogResult.OK; this.Dispos ...