【算法趣题】硬币组合
题目描述:
当下,坐公交或者地铁时大部分人都是刷卡的。不过,时至今日还在用现金支付的人还是比想象的多。本题我们以安置在公交上的零钱兑换机为背景。这个机器可以用纸币兑换到 10 日元、50 日元、100 日元和 500 日 元硬币的组合,且每种硬币的数量都足够多(因为公交接受的最小额度 为 10 日元,所以不提供 1 日元和 5 日元的硬币)。 兑换时,允许机器兑换出本次支付时用不到的硬币。此外,因为在 乘坐公交时,如果兑换出了大量的零钱会比较不便,所以只允许机器最多兑换出 15 枚硬币。譬如用 1000 日元纸币兑换时,就不能兑换出 “100 枚 10 日元硬币”的组合。
问题:
求兑换 1000 日元纸币时会出现多少种组合?注意,不计硬币兑出的先后顺序。
问题分析:
第一眼看完题感觉用递归运算解析比较容易,但后面题目约束(不计硬币兑出的先后顺序)使得递归有缺陷。因为递归会将所有可能的结果包括顺序全部列出,后续去重特别麻烦。
问题解决:
首先尝试用递归解决,代码如下:
#include <stdio.h>#define TOTALMONEYNUM 15int iCount = 0;void cutt(int money, int i500num, int i100num, int i50num, int i10num)
{if(i500num + i100num + i50num + i10num <= TOTALMONEYNUM){if(money < 0){return;}if(money == 0){iCount++;return;}if(money >= 500){cutt(money - 500, i500num + 1, i100num, i50num, i10num);}if(money >= 100){cutt(money - 100, i500num, i100num + 1, i50num, i10num);}if(money >= 50){cutt(money - 50, i500num, i100num, i50num + 1, i10num);}if(money >= 10){cutt(money - 10, i500num, i100num, i50num, i10num + 1);}}
}int main()
{cutt(1000, 0, 0, 0, 0);printf("iCount = %d\n", iCount);return 0;
}
运行结果为:iCount = 569193,很显然这里面有重复的组合,此解法有问题。
运用非递归解决思路代码如下:
#include <stdio.h>#define TOTALMONEYNUM 15int iCount = 0;int iNumMoney(int iMoney, int iCoin)
{if(iMoney/iCoin < TOTALMONEYNUM){return iMoney/iCoin;}else{return TOTALMONEYNUM;}
}int main()
{int i500MaxNum = iNumMoney(1000, 500);int i100MaxNum = iNumMoney(1000, 100);int i50MaxNum = iNumMoney(1000, 50);int i10MaxNum = iNumMoney(1000, 10);int i500 = 0, i100 = 0, i50 = 0, i10 = 0;for(i500 = 0; i500 <= i500MaxNum; i500++){for(i100 = 0; i100 <= i100MaxNum; i100++){for(i50 = 0; i50 <= i50MaxNum; i50++){for(i10 = 0; i10 <= i10MaxNum; i10++){if(i500 + i100 + i50 + i10 <= 15 && 500*i500 + 100*i100 + 50*i50 + 10*i10 == 1000){printf("500 : %d, 100: %d, 50 :%d, 10 : %d\n", i500, i100, i50, i10);iCount++;}}}}}printf("iCount : %d\n", iCount);return 0;
}
运行结果为:
【算法趣题】硬币组合相关推荐
- 程序员的算法趣题Q05: 硬币兑换
目录 1. 问题描述 2. 递推表达式 3. 代码及测试 1. 问题描述 本题来自<程序员的算法趣题>中的第5题. 公交车上的零钱兑换机可以将纸币兑换成10日元.50日元.100日元和50 ...
- python代码实践-程序员的算法趣题-Q05
Q05 还在用现金支付吗 当下,坐公交或者地铁时大部分人都是刷卡的.不过,时至今日还在用现金支付的人还是比想象的多.本题我们以安置在公交上的零钱兑换机为背景. 这个机器可以用纸币兑换到 10 日元.5 ...
- 100%的程序员都想挑战的算法趣题!| 码书
计算机的世界每天都在发生着深刻的变化.新操作系统的发布.CPU性能的提升.智能手机和平板电脑的流行.存储介质的变化.云的普及--这样的变化数不胜数. 在这样日新月异的时代中,"算法" ...
- 我敢打赌,这是98%的程序员都想挑战的算法趣题!
计算机的世界每天都在发生着深刻的变化.新操作系统的发布.CPU性能的提升.智能手机和平板电脑的流行.存储介质的变化.云的普及--这样的变化数不胜数. 在这样日新月异的时代中,"算法" ...
- 100% 的程序员都想挑战的算法趣题!
作者 | 图小敏 计算机的世界每天都在发生着深刻的变化.新操作系统的发布.CPU性能的提升.智能手机和平板电脑的流行.存储介质的变化.云的普及--这样的变化数不胜数. 在这样日新月异的时代中,&quo ...
- php算法求出一个数可以被分解成多少个_程序员的算法趣题
计算机的世界每天都在发生着深刻的变化.新操作系统的发布.CPU性能的提升.智能手机和平板电脑的流行.存储介质的变化.云的普及--这样的变化数不胜数. 在这样日新月异的时代中,"算法" ...
- 程序员的算法趣题Q57: 最快的联络网
目录 1. 问题描述 2. 解题分析 2.1 学生的状态 2.2 学生状态转移 Case-T1:Do nothing, just wait Case-T2:给处于S0状态的学生打电话 Case-T3: ...
- 程序员的算法趣题Q13: 满足字母算式的解法
目录 1. 问题描述 2. 解题思路 3. 代码及测试 4. 优化 1. 问题描述 所谓字母算式,就是用字母表示的算式,规则是相同字母对应相同数字,不同字母对应不同数字,并且第一位字母的对应数字不能是 ...
- 程序员的算法趣题Q29: 合成电阻的黄金分割比
目录 1. 问题描述 2. 解题分析 2.1 分割成两组 2.2 N=5时的分割例 2.3 阻值计算例 2.4 算法实现流程 3. 代码及测试 4. 后记 4.1 分割的洞见 4.2 另一种思路 1. ...
- 程序员的算法趣题Q10: 轮盘的最大值
目录 1. 问题描述 2. 解题分析 3. 代码及测试 1. 问题描述 轮盘游戏被称为"赌场女王".流传较广的轮盘数字排布和设计有"欧式规则"和"美式 ...
最新文章
- Android开发者指南(18) —— Web Apps Overview
- 人工智能模型数据泄露的攻击与防御研究综述
- Linux下快捷键使用
- 微信v3app支付php,php微信支付之APP支付方法_php技巧
- 360浏览器卸载_陈蛋蛋碎碎念—如何完美地卸载流氓软件
- (十五)非常全面的TCPIP面试宝典-进入大厂必备总结
- 论文浅尝 | Dynamic Weighted Majority for Incremental Learning
- Shell判断参数是否为数字的6种方法(是否为整形)
- 数据太多加滚动标题不动_音乐数据挖掘导引(四)
- Flink学习笔记04:将项目打包提交到Flink集群上运行(Scala版)
- 【英语学习】【WOTD】foray 释义/词源/示例
- 油价下降,全国人民都高兴
- miRNA数据库篇——HMDD:miRNA相关疾病数据库
- 用计算机上初中英语课的方法,如何上好初中英语读写课
- 方舟编译器开源,华为自家开源平台面世!(附编译过程)
- Codeforces1221 C. Perfect Team
- k8s-高可用部署-calico插件
- 科研入门-国际期刊会议
- 【map】高德地图点聚合—按索引聚合
- java中包中建包怎么创建,Java集成开发环境 – IDEA中建包时如何把包分开