用1元,2元,5元,10元,20元和50元的纸币组成100元,共有多少种情况
2008-11-06 10:30
1246 查看
问题帖子:
http://topic.csdn.net/u/20081016/14/8E1B21C7-DBC8-40CE-BA93-28C4CAC4E461.html
用1元,2元,5元,10元,20元和50元的纸币组成100元,共有多少种情况。
要求写出除了多重循环方案之外的另一种程序代码,要求输出总方案数和每种方案中各纸币的个数。
这个是原题,当然,如果你有循环的实现也可以贴上来。
我的回复:
我来解一些,就用最简单的循环。。本来想再写个递归。。。大同小异,累死我了,忽略~
递归方法:(整体结构copy自91楼,并改进之)
------------------------------------ Analysis ------------------------------------
也许循环和递归不是最高效的方法,但却是最易懂的写法~而容易阅读的代码对于日后的维护也起着至关重要的作用。
也许有人可以写出更简洁的代码,但如果那简短高效代码却要花费别人1、2个小时去琢磨,那其实也不是什么好代码。
KISS: Keep It Simple Stupid~ remember?
但是,单纯的 100 × 50 × 20 × 10 ×5 × 2 粗暴的循环我个人觉得也是蛮“楞”的,所以综合计算机的高效和咱们人类的智慧,运用诸如统筹啊、线性规划啊(一堆乱七八糟的学术名词,用来提升自己的“表面”素质)等各种分析手段,我们可以发现:
当某次循环的等于或者大于限制时,接下来的循环就是完全没必要的。
也就是说:如果 99 张 1元钱了, 那么当我们进入 2 元钱的第一次循环时,不难发现 99 + 2 = 101 。。。这已经超出了题目要求,那必然两张2元钱或者再来一张5元钱更不可能符合范围要求,因此可以直接跳出循环(break)进入下一轮~
------------------------------------ Analysis ------------------------------------
/*
* 另一种思路:有一个经典的例子,大家一定都听说过:
* 问,有人拿着1升的水桶,有人拿着2升的,有人拿着5、10、20升的,
* 大家都排队接水,那么如何可以使得整体时间最短?答案是按照从小
* 到大的顺序大家重新排队这样整体时间最短。(这是理想情况,但事
* 实上人作为感情动物,是不可能会这样重新排队的)
*
* 因此,如果按照面值从【大】到【小】的顺序循环,那么除了完整的
* 执行一次 100 × 50 × 20 × 10 ×5 × 2 的循环,找一些机制
* (improvement)就可以使得时间进一步缩短。
*
* 注意:因为是从最内圈开始数的,所以“先接水”的人应该在最内圈。
*
* 91楼的代码是按照1.2.5.10.20.50的结构写的~但如果按照50.20.10.5.2.1
* 的顺序循环,那么第一次的1元钱我们可以知道只需要循环15次(之前
* 已经有85元钱了),第二次13次…………但这时判断终止条件又不一样了,
* 需要新的条件,欢迎高手探讨一下。
*/
PS:如果是按照“接水”这种规划,似乎用点GoTo语句加上一些在for()括号外的++行为似乎可以达到这种效果?是不是会更接近AI?哈哈
http://topic.csdn.net/u/20081016/14/8E1B21C7-DBC8-40CE-BA93-28C4CAC4E461.html
用1元,2元,5元,10元,20元和50元的纸币组成100元,共有多少种情况。
要求写出除了多重循环方案之外的另一种程序代码,要求输出总方案数和每种方案中各纸币的个数。
这个是原题,当然,如果你有循环的实现也可以贴上来。
我的回复:
我来解一些,就用最简单的循环。。本来想再写个递归。。。大同小异,累死我了,忽略~
递归方法:(整体结构copy自91楼,并改进之)
public static void Main() { int count = 0; // KEY-1:这里引入一些变量,减少递归次数 int _CNY1Sum = 0, _CNY2Sum = 0, _CNY5Sum = 0; int _CNY10Sum = 0, _CNY20Sum = 0, _CNY50Sum = 0; int _CNY100Sum = 0; int Total = 0; int Limit = 100; Array<int> distribution[] = { 0, 0, 0, 0, 0, 0 }; //1元组成的情况,最多有100种 for (int a = 0; a <= 100; a++) { // initial each round ResetDistribution(distribution, distribution.size); // improvement Total = 0; _CNY1Sum = 1 * a; distribution[0] = a; Total = _CNY1Sum; if (Total == Limit) { count++; PrintSequence(distribution); continue; } if (Total > Limit) { break; } //2元的情况,最多有50种可能 for (int b = 0; b <= 50; b++) { // improvement _CNY2Sum = 2 * b; distribution[1] = b; Total = _CNY2Sum + _CNY1Sum; if (Total == Limit) { count++; PrintSequence(distribution); break; } if (Total > Limit) { break; } //5元的情况,最多有20中可能 for (int c = 0; c <= 20; c++) { // improvement _CNY5Sum = 5 * c; distribution[2] = c; Total = _CNY5Sum + _CNY2Sum + CNY1Sum; if (Total == Limit) { count++; PrintSequence(distribution); break; } if (Total > Limit) { break; } //10元的情况,最多10种可能 for (int d = 0; d <= 10; d++) { // improvement _CNY10Sum = 10 * d; distribution[3] = d; Total = _CNY10Sum + _CNY5Sum + _CNY2Sum + _CNY1Sum; if (Total == Limit) { count++; PrintSequence(distribution); break; } if (Total > Limit) { break; } //20元的情况,最多5种可能 for (int e = 0; e <= 5; e++) { // improvement _CNY20Sum = 20 * e; distribution[4] = e; Total = _CNY20Sum + _CNY10Sum + _CNY5Sum + _CNY2Sum + _CNY1Sum; if (Total == Limit) { count++; PrintSequence(distribution); break; } if (Total > Limit) { break; } //50元的情况,最多2种可能 for (int f = 0; f <= 2; f++) { // improvement _CNY50Sum = 50 * f; distribution[5] = f; Total = _CNY50Sum + _CNY20Sum + _CNY10Sum + _CNY5Sum + _CNY2Sum + _CNY1Sum; if (Total == Limit) { count++; PrintSequence(distribution); break; } if (Total > Limit) { break; } } } } } } } Console.WriteLine("共有{0}种可能情况", count); } // new methods private void ResetDistribution(Array<int> myZone, int mySize) { for (int i = 0; i < mySize; i++) myZone[i] = 0 } private void PrintSequence(Array<int> myZone) { Console.WriteLine("Possible Solution for CNY100: " + myZone[0] + " " + myZone[1] + " " + myZone[2] + " " + myZone[3] + " " + myZone[3] + " " + myZone[4] + " " + myZone[5]); } /* * Author: Leemax Li * Created: 2008.11.05 * MSN: leemax@live.com * */
------------------------------------ Analysis ------------------------------------
也许循环和递归不是最高效的方法,但却是最易懂的写法~而容易阅读的代码对于日后的维护也起着至关重要的作用。
也许有人可以写出更简洁的代码,但如果那简短高效代码却要花费别人1、2个小时去琢磨,那其实也不是什么好代码。
KISS: Keep It Simple Stupid~ remember?
但是,单纯的 100 × 50 × 20 × 10 ×5 × 2 粗暴的循环我个人觉得也是蛮“楞”的,所以综合计算机的高效和咱们人类的智慧,运用诸如统筹啊、线性规划啊(一堆乱七八糟的学术名词,用来提升自己的“表面”素质)等各种分析手段,我们可以发现:
当某次循环的等于或者大于限制时,接下来的循环就是完全没必要的。
也就是说:如果 99 张 1元钱了, 那么当我们进入 2 元钱的第一次循环时,不难发现 99 + 2 = 101 。。。这已经超出了题目要求,那必然两张2元钱或者再来一张5元钱更不可能符合范围要求,因此可以直接跳出循环(break)进入下一轮~
------------------------------------ Analysis ------------------------------------
/*
* 另一种思路:有一个经典的例子,大家一定都听说过:
* 问,有人拿着1升的水桶,有人拿着2升的,有人拿着5、10、20升的,
* 大家都排队接水,那么如何可以使得整体时间最短?答案是按照从小
* 到大的顺序大家重新排队这样整体时间最短。(这是理想情况,但事
* 实上人作为感情动物,是不可能会这样重新排队的)
*
* 因此,如果按照面值从【大】到【小】的顺序循环,那么除了完整的
* 执行一次 100 × 50 × 20 × 10 ×5 × 2 的循环,找一些机制
* (improvement)就可以使得时间进一步缩短。
*
* 注意:因为是从最内圈开始数的,所以“先接水”的人应该在最内圈。
*
* 91楼的代码是按照1.2.5.10.20.50的结构写的~但如果按照50.20.10.5.2.1
* 的顺序循环,那么第一次的1元钱我们可以知道只需要循环15次(之前
* 已经有85元钱了),第二次13次…………但这时判断终止条件又不一样了,
* 需要新的条件,欢迎高手探讨一下。
*/
PS:如果是按照“接水”这种规划,似乎用点GoTo语句加上一些在for()括号外的++行为似乎可以达到这种效果?是不是会更接近AI?哈哈
相关文章推荐
- 用1元,2元,5元,10元,20元和50元的纸币组成100元,共有多少种情况
- 用1元,2元,5元,10元,20元,50元和10元的纸币组成200元,共有多少种情况
- 编程实现 1元,2元,5元,100元纸币组成800元,共有多少种情况。?
- 用1元,2元,5元,10元,20元,50元组合成100元
- 有1元、5元、10元、20元、50元、100元硬币无数个,问100000元的组合方法有多少个
- 从键盘输入一个指定金额(以元为单位,如345.78),然后显示支付该金额的各种面额人民币数量,要求显示100元、50元、10元、5元、2元、1元、5角、1角、5分、1分各多少张
- 如果每个老师的工资额都知道,最少需要准备多少张人民币,才能在给每位老师发工资的时候都不用老师找零呢? 这里假设老师的工资都是正整数,单位元,人民币一共有100元、50元、10元、5元、2元和1元六种。
- 有10元,5元,2元,1元四种面值的人民币,问组成100元钱有多少种组合?
- * 输出由1元,2元,5元纸币组成100元钱的所有方案 1,1,...,1=100 2,2,...,2=100
- 100元 50元 20元 10元 5元 1元 标准尺寸
- 用100元换10元、5元和1元的纸币共50张,能换各种纸币多少张。
- 用100元人民币兑换10元,5元,1元的纸币(每种都要有)共50张,计算有多少种兑换方案
- 一个很原始的背包问题。。。就是100元换零钱1元,2元,5元,10元,50元。。
- 百钱百鸡:公鸡5元一只,母鸡3元一只,小鸡1元3只,100元要买100只鸡,共有几种情况
- C语言求把100元换成20元,10元,5元的纸币.要求每种纸币至少有一张。以及最少张数
- 百钱百鸡:公鸡5元一只,母鸡3元一只,小鸡1元3只,100元要买100只鸡,共有几种情况
- 百钱百鸡:公鸡5元一只,母鸡3元一只,小鸡1元3只,100元要买100只鸡,共有几种情况
- 百钱百鸡:公鸡5元一只,母鸡3元一只,小鸡1元3只,100元要买100只鸡,共有几种情况
- 百钱百鸡:公鸡5元一只,母鸡3元一只,小鸡1元3只,100元要买100只鸡,共有几种情况
- 深入解析之将100元兑换为1元、5元、10元的零钱,请问有多少种兑换方法