Time limit: 3.000 seconds
限时:3.000秒
Problem
问题
New Zealand currency consists of 50, 10, and 2, $1, 50c, 20c, 10c and 5c coins. Write a program that will determine, for any given amount, in how many ways that amount may be made up. Changing the order of listing does not increase the count. Thus 20c may be made up in 4 ways: 1 × 20c, 2 × 10c, 10c+2 × 5c, and 4 × 5c.
新西兰的流通货币中,纸币分为五种:100元、50元、20元、10元和5元;硬币分为六种:2元、1元、50分(即五毛)、20分、10分和5分。写一个程序计算出对于给定的任意金额,可以有多少种不同的钱币组合方式。仅仅改变顺序的不能算。比如20分可以有以下4种组合方式:1 × 20分, 2 × 10分, 10分+2 × 5分, 和4 × 5分。
Input
输入
Input will consist of a series of real numbers no greater than $300.00 each on a separate line. Each amount will be valid, that is will be a multiple of 5c. The file will be terminated by a line containing zero (0.00).
输入由一组实数构成,每个实数都不会超过300.00元,并且都独占一行。金额都是有效的,即都是5分的整数倍。输入由一行零元(0.00)表示结束。
Output
输出
Output will consist of a line for each of the amounts in the input, each line consisting of the amount of money (with two decimal places and right justified in a field of width 6), followed by the number of ways in which that amount may be made up, right justified in a field of width 17.
每行输入对应一行输出,包括总金额(保留两位小数并右对齐至第6列),后面是可以组成该金额的方法数,右对齐宽度为17。
Sample Input
输入示例
0.20
2.00
0.00
Sample Output
输出示例
0.20 4
2.00 293
Analysis
分析
此题较难,是一个子集合问题。可以用递归式直接计算任意给定金额的组合方案,但是所给的数据可能非常大,用递归的话肯定会TLE,因此必须通过递推的方式生成所有可能金额的答案,运行时直接查表即可。
建表过程如下:首先任何金额都可仅由5分组成这1种方案,如果金额刚好等于某一种钱币,就还有这一种方案,因此10分有2种方案。15分的第一种方案可仅由5分组成,要计算由10分或5分组成(不包括前面算过的全部5分的情况)的情况,可先减掉10分(因为这种情况至少包括一个10分),剩下的5分就只有1种情况,因此共有2种方案。20分的第一种方案可由5分组成;第二种情况先减掉10分还剩10分,而10分由10分或5分组成的情况有2种,因此都要计入;最后一种方案就是直接使用20分,因此一共4种方案。其余的以此类推。
注意到所有钱数都是5的整数倍,因此可以将货币面值和查询的金额统一除以5再计算。要注意按指定的格式输出结果,并在输入0时退出程序。
这个思路讲起来很麻烦,如果您有更好的公式化理论敬请提出!
Solution
解答
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #include <iomanip> #include <iostream> using namespace std; int main( void ) { //钱币数,全部除以5 int Coins[] = {1, 2, 4, 10, 20, 40, 100, 200, 400, 1000, 2000}; long long Tbl[6001] = {1}; //各金额组合方案数总表 //以下开始建表,按钱币种类进行循环 for ( int i = 0; i < 11; i++){ //仅使用i之前的钱币进行组合,但不包括不使用i的情况 for ( int j = Coins[i]; j < 6001; j++) { //先减掉第i种钱币,然后加上剩下的金额的组合方案数 Tbl[j] += Tbl[j - Coins[i]]; } } //以下为设定格式,查表输出结果。 cout << fixed << showpoint << setprecision(2); for ( float fIn; cin >> fIn && fIn != 0; cout << endl) { cout << setw(6) << fIn << setw(17) << Tbl[( int )(fIn * 20 + 0.5f)]; } return 0; } |
![]() |
作者:王雨濛;新浪微博:@吉祥村码农;来源:《程序控》博客 -- http://www.cnblogs.com/devymex/ 此文章版权归作者所有(有特别声明的除外),转载必须注明作者及来源。您不能用于商业目的也不能修改原文内容。 |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
· .NET Core内存结构体系(Windows环境)底层原理浅谈
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· DeepSeek 解答了困扰我五年的技术问题。时代确实变了!
· 本地部署DeepSeek后,没有好看的交互界面怎么行!
· 趁着过年的时候手搓了一个低代码框架
· 推荐一个DeepSeek 大模型的免费 API 项目!兼容OpenAI接口!