noip模拟 马云 Mr_H
2017-08-29 12:33
162 查看
题目描述:
因讨厌马云而彻底放弃网购,他的日常用品都要到商场去购买,而且必须付现金。但是现金购买,经常会遇到找零的问题,那么现在请你帮助他解决这样一个问题:现在 Mr_he 手上有 n 种不同面值的硬币,每种硬币有无限多个。为了方便购物,他希望带尽量少的硬币,但是要能组合出 1 到 m 之间的任意值。
输入:
第一行为两个整数:m 和 n,他们的意义如题目描述。接下来的 n 行,每行一个整数,第 i+1 行的整数表示第 i 种硬币的面值。
输出:
最少需要携带的硬币数量,如果无解则输出-1。
样例输入:
20 4 1 2 5 10
样例输出:
5
简析:
首先判断有无解,如果最小面额硬币大于1则无解,因为搭配不出1,如果有一则有解,因为所有面额都可以由1堆积出来。 接下来思考一个问题,假设当前硬币可以组合出1到5的任意面额,那么添加一枚面额为6的硬币就可以搭配出1到11的任意面额,于是我们依照这个思路,假设当前硬币面值的和为sum,每一次添加硬币时,从大到小搜索,将搜索到的第一枚面值小于等于sum+1的硬币加入,(sum+1是上限),并将计数器+1,更新sum值。
代码:
#include<stdio.h> #include<string.h> #include<algorithm> #include<iostream> using namespace std; int a[1100]; int main(){ int n,m; scanf("%d%d",&m,&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); sort(a+1,a+n+1); //注意排序 if(a[1]!=1){ printf("-1"); return 0; } int sum=0,ans=0; while(1){ if(sum>=m){ printf("%d",ans); return 0; } for(int i=n;i>=1;i--) //从大到小 if(a[i]<=sum+1){ sum+=a[i]; ans++; break; } } }
相关文章推荐
- 【NOIP2016提高A组模拟10.15】算循环
- 【NOIP模拟题】T3 【递归】【复杂公式】【模拟】
- [NOIP2017模拟]裁剪表格
- CodeVS 1107 等价表达式【NOIP2005】【模拟
- JZOJ 4628 立方体【NOIP2016提高A组模拟7.15】
- [JZSC2016] 【NOIP2016提高A组模拟7.15】总结
- 【NOIP2016提高A组模拟10.15】最大化
- 【NOIP2014模拟11.2A组】福慧双修
- 记忆化搜索(游戏NOIP17提高模拟训练11)
- JZOJ-senior-3910. 【NOIP2014模拟11.1A组】Idiot 的间谍网络
- 【NOIP2016提高A组模拟7.17】寻找
- 锦标赛【NOIP2016提高A组模拟7.17】
- [NOIP模拟] 拆网线 树形DP
- 【NOIP模拟】Angel Beats!
- [jzoj]3729. 【NOIP2014模拟7.10】表达式的值(exp) (分块转化模型)
- [NOIP模拟][bfs][dp][CSD][表达式的计算]
- JZOJ 3053 【NOIP2012模拟10.25】旅行
- 【NOIP2016提高A组模拟10.15】最大化
- 洛谷1071 潜伏者 NOIP2009 字符串模拟
- NOIP模拟(10.24)T1 建设图