100元换成1、5、10的零钱共有多少种方案?
一 ,每种至少一张,实际应为至少10元、5元各一张,1元的5张。共20元,剩下的80元可任意分配。
二,80元的零钱可以如下:
8张10元。1种
7张10元,5元的2、1、0张(差额为1元,下同)。3种
6张10元,5元的4、3、2、1、0张。5种
5张10元,5元的6、5、4、3、2、1、0张。7种
......
1张10元,5元的14、13.....6、5、4、3、2、1、0张。15种
0张10元,5元的16、15、14、13.....6、5、4、3、2、1、0张。17种
三,总的换法为
1+3+5+.....+15+17=81种
看到这个题目的第一感觉就是一个三元一次方程的求解,编程的话,就是三个for循环外加个if判断,瞬间KO。对这个题目来说效率也是可以接受的。可是这根本没有体现出算法的优势。下面我们来仔细推敲下这里面隐藏的规律。
根据上图的规律,即可得到如下代码:
/**
* 1、求解特定实例:要将100元兑换为1元、5元、10元的零钱,请问有多少种兑换方法?
*
* @return
* @author chenchanghan
*/
public static int getDivideWays() {
int count = 0;
for (int i = 0, size = 100 / 10; i <= size; i++) {
// 针对10的每个场景,计算5的组合情况(即,从0个5 到 n( n=(100 - i * 10)/5
// )个5共n+1种情况
count += (100 - i * 10) / 5 + 1;
}
return count;
}
到这里,这个就算解完了,但是这里确实因为分解的元素中包含1,将问题变的简单化了,如果不是1、5、10而是随意的三个数字,改怎么解决呢?同样还是要找出规律来。
下面我们就来分析下10、5、3如何组合成100吧。
首先,0个10的情况下,5和3怎么组合成100呢?正好20*5=100,显然这是不存在10的情况下出现最多5的情况,那还有没有其他的组合情况呢?这时我们就要用到一个最小公倍数(3和5的最小公倍数是15),很显然,我们就可以将”3个5替换成5个3“了。因为最多20个5,所以我们可以继续用”3个5替换成5个3“,直到最后剩下2个5。综上0个10的情况下,5可以出现的次数分别为20、17、14、11、8、5、2,所以该场景下共有7中组合方式。
其次,1个10的情况下,5和3怎么组合成100呢?我们还是从5来出发,5*18=90,1个10的情况下,组合成100,最多可以出现18次,同理还是用”3个5替换成5个3“。最终1个10的情况下,5可以出现的次数分别为18、15、12、9、6、3、0。该场景下也有7种组合方式。
同理,依次分析下去。
根据上面的规律,得出代码如下:
/**
* 2、组合元素一般化:将total元兑换为large元、middle元、small元的零钱,请问有多少种兑换方法?
*
* @param total
* @param large
* @param middle
* @param small
* @return
* @author chenchanghan
*/
public static int getDivideWays(int total, int large, int middle, int small) {
if (total > 0 && small > 0 && middle > small && large > middle) {
int count = 0;
int LCM = getLeastCommonMutiple(middle, small);
int substituteUnit = LCM / middle;
for (int i = 0, size = total / large; i <= size; i++) {
int restTotal = total - i * large;
if (restTotal > 0) {
// actualMaxMiddleNum>=0,表示restTotal正好可以有x个middle和y个small拼凑起来(x、y是大于等于0的整数)
int actualMaxMiddleNum = getActualMaxMiddleNum(restTotal, middle, small);
if (actualMaxMiddleNum >= substituteUnit) {
// actualMaxMiddleNum >=substituteUnit,表示可以将substituteUnit个middle替换成LCM/small个small
// 可以换多少次呢?显然可以换0、1...actualMaxMiddleNum/substituteUnit,即:actualMaxMiddleNum/substituteUnit+1
count += actualMaxMiddleNum / substituteUnit + 1;
} else if (actualMaxMiddleNum >= 0) {
// 0<=actualMaxMiddleNum
}
} else {
// 正好被large完美匹配了
count++;
}
}
return count;
} else {
throw new IllegalArgumentException();
}
}
/**
* 获得方程:x*middle + y*small = restTotal 中x最大的取值。
*
* @param restTotal
* @param middle
* @param small
* @return
* @author chenchanghan
*/
private static int getActualMaxMiddleNum(int restTotal, int middle, int small) {
int modMiddle = restTotal % middle;
int maxMiddleNum = restTotal / middle;
int actualMaxMiddleNum = -1;
if (modMiddle == 0 || modMiddle == small) {
actualMaxMiddleNum = maxMiddleNum;
} else {
// 无法使用最大数量(即:maxMiddleNum)的middle和small组合成restTotal,
// 则需要逐步减少middle的个数,进而增加small的个数,来尝试组合成restTotal。
int minusMiddleNum = getMinusMiddleNum(middle, small, modMiddle, maxMiddleNum);
if (minusMiddleNum > 0) {
// 表示可以形成一个拥有最大middle数的组合,即: (maxMiddleNum - minusMiddleNum)*middle + y*small = restTotal ;
actualMaxMiddleNum = maxMiddleNum - minusMiddleNum;
} else {
// middle和small无论怎么组合都无法拼凑成restTotal,即:x*middle + y*small = restTotal 的整数解不存在
actualMaxMiddleNum = -1;
}
}
return actualMaxMiddleNum;
}
/**
*
* @param middle
* @param small
* @param modMiddle
* @param maxMiddleNum
* @return
* @author chenchanghan
*/
private static int getMinusMiddleNum(int middle, int small, int modMiddle, int maxMiddleNum) {
int minusMiddleNum = -1;
for (int i = 1; i <= maxMiddleNum; i++) {
if ((middle * i + modMiddle) % small == 0) {
minusMiddleNum = i;
break;
}
}
return minusMiddleNum;
}
/**
* 求两个数的最小公倍数。
*
* @param middle
* @param small
* @return
* @author chenchanghan
*/
private static int getLeastCommonMutiple(int m, int n) {
return m * n / getGreatestDivisor(m, n);
}
/**
* 求两个数的最大公约数。
*
* @param m
* @param n
* @return
* @author chenchanghan
*/
private static int getGreatestDivisor(int m, int n) {
int tmp = 0;
if (m < n) {
tmp = m;
m = n;
n = tmp;
}
while ((tmp = m % n) != 0) {
m = n;
n = tmp;
}
return n;
}
我们再来推广下,将分解的元素变成3个以上,具体见如下代码:
/**
* 3、元素个数一般化:将total元兑换为a元、b元、c元、....的零钱,请问有多少种兑换方法?
*
* @param total
* @param elements
* @return
* @author chenchanghan
*/
public static int getDivideWays(int total,int[] elements){
if(elements!=null && elements.length>=3){
int count = 0 ;
if(elements.length == 3){
count += getDivideWays(total,elements[0],elements[1],elements[2]);
}else{
int large = elements[0];
int[] subElements = new int[elements.length-1];
System.arraycopy(elements, 1, subElements, 0, subElements.length);
for (int i = 0, size = total / large; i <= size; i++) {
int restTotal = total - i * large;
if (restTotal != 0) {
count += getDivideWays(restTotal, subElements);
} else {
count++;
}
}
}
return count ;
}else{
throw new IllegalArgumentException();
}
}
要将一元钱换成1分,2分,和5分的硬币,每种硬币的个数大于0,且为5的倍 ...
include<stdio.h> main(){ int i,j,k;printf("1分\\t2分\\t5分\\n");for(i=1;i<100;i++)for(j=1;j<50;j++)for(k=1;k<20;k++)if(i%5==0&&j%5==0&&k%5==0&&i+2*j+5*k==100)printf("%d\\t%d\\t%d\\n",i,j,k);} 如图所示,望采纳。。。
人民币的换算题一年级
2. 几十几角换算成几元几角时,先想几十角是几元,几元和剩下的几角合起来就是几元几角。二、人民币的简单计算:1. 相同单位的数可以直接相加减。2. 单位不同时,要先统一单位,再计算。注意。以上两个重要的知识点就是本次课程的核心内容,主要给大家提供了解题的方法和解题的技巧,在实际的...
五张一元可以换成多少张五元也可以换成多少张五角?
五张一元可以换1张五元(1×5=5),也可以换成10张五角的(5÷0.5=10)
把一元钱全兑换成1分,2分,5分的硬币,有多少种兑换方法,用简单一点的...
1. 5个1分的和 1个5分的 2. 2个2分, 1个1分,1个5分 3. 10个1分的 4. 5个2分 5. 2个5分的 不知道我是不是回答对了.谢谢!
有一张二元的纸币,要想换成角票(五角、二角、一角),一共有多少种换法...
这个题目的意思是把一张2元的纸币兑换成1角、2角和5角的三种纸币,这本质上就是一道数学问题,我们可以把2元看作20角,那么题目就转化成将20换成1、2、5三种数值,一共有多少种换法。解决这个问题我们需要分类考虑,先考虑只换成一种面值的纸币,看下有多少种方法,再考虑换成两种面值的纸币,有...
3元可以换几个一元几个五角几个一角一共换7个?
对于这个问题,我们需要将3元换成1元、5角和1角的纸币或硬币,总共需要7张。但是,根据换算,这是不可能的。因为如果我们要至少5张1角的话,就是0.5元,剩下2.5元。这2.5元需要2张1元和1张5角的,加起来就已经是8张了。所以,根据这个逻辑,我们至少需要换8张才能达到7张的总数,这是不...
VB编程 把一张一元钞票,换成一分,二分和五分硬币,每种至少5枚,问有多...
Private Sub Command1_Click()Dim n%,x%,y%,z n = 0 For x=5 to 100 For y=5 to 50 For z=5 to 20 If x + y * 2 + z * 5 = 100 Then n=n+1 Next Next Next Print n End Sub 这样做,答案就是205。
把一元钱换成角币,有多少种换法(人民币
一元可以换成 10个一角,两个五角,一个五角五个一角。
将100元钱兑换成10元5元1元c编程求不同的兑换法数,要求每种兑法中都...
最笨的方法 。。。三重循环 每张钱都是从1开始循环。。。聪明的方法 二重循环生成10元和5元的 然后用100元去减去生成的只要不为0就成立 而且还能够输出
一张10元可以换成()张元和()张1元?
一张10元可以换成两张5元或者10张一元。和表示加即一张10元表示一张5元,两张两元和一张一元。破一张5元和5张一元。
拱幸典灵: 枚举2元、5元、10元纸币分别有几张,在循环中计数即可. 1 2 3 4 5fori := 1to50doforj := 1to20dofork := 1to10doif2* i + 5* j + 10* k <= 100theninc( ans );
西夏区17120492252: 求100元 换成 1元 5元 和10元的钱 有多少换法!用C语言编写?
拱幸典灵: #include<stdio.h> void main() { int x=0,y=0,z=0; for(x=0;x<=10;x++) for(y=0;y<=20;y++) if(10*x+5*y<100) printf("10元%d张,5元%d张,1元%d张\n",x,y,100-10*x-5*y); }
西夏区17120492252: 将100元兑换成1元,5元,10元有多少种换法,怎么换??? - ?
拱幸典灵: 设1元的张数为x,5元的为y,10元的为z 1*x+5*y+10*z=100 ∵0<z<10 ∴当z=9时,y=1,x=5(一种); z=8,y=3,x=5;z=8,y=2,x=10;z=8,y=1,x=15(三种); 注意观察发现y的个数等于种数;z=7,y=5......(五种),z=6,y=7.....七种;z=5,y=9......九种,......;z=1,y=17......十七种; 综合得(1+17)*9\2=81(种)
西夏区17120492252: C语言,程序设计.用一百元人民币兑换成1元、5元和10元币,共有多少种不同的兑换方法.才用循环来做. - ?
拱幸典灵: #include "stdio.h" #include "math.h" main() { printf("共有%d种不同的兑换方案",fun (int n)) } fun(int m){ int i;for(i=0;i<=10;i++){int j;for(j=0;j<=20;j++){int k;for(k=0;k<=100;k++){if(10i+5j+k==100) m+=1}}if(i==10) return m}}
西夏区17120492252: 一张100元人民币换成1元,2元,5元,10元的纸币,每种纸币至少一张,问同学们共有几种方法 - ?
拱幸典灵:[答案] 有16种,(下面以括号里的数字代替个数) 一.当5元有2个时,10元可以有(7个.5个.3个.1个),20元可以有(1个.2个.3个.4个).10元和20元是对应的,即;当10元是7个时,20元是1个.下面一样. 二.当5元有4个时,10元可以有(6个.4个.2个),...
西夏区17120492252: 某商店要把面值100元的一张人民币换成零钱,现有足够面值为50元,20元,10元的人民币,则共有几种换法? - ?
拱幸典灵:[答案] 共有10种换法
西夏区17120492252: 将100换成1元,5元,10元的零钱有多少种换法 - ?
拱幸典灵: 1.10张1元2.5张2元3.2张5元4.4张2元和2张1元5.3张2元和4张1元6.2张2元和6张1元7.1张2元和8张1元8.1张5元和5张1元9.1张5元和2张2元和1张1元10.1张5元和1张2元和3张1元
西夏区17120492252: 100元换成1元,5元,10元,20元的任意组合,共有多少种组合方法 - ?
拱幸典灵:[答案] 总共286请在此输入您的回答
西夏区17120492252: 妈妈用一张100元兑换成5元和10元的零钱共14张,其中10元的人民币有几张? - ?
拱幸典灵: 6张 6*10+5*8=100 可以设五元的X张 十元的Y张 用X+Y=14 5X+10Y=100 方程组求解
西夏区17120492252: 100元换成10元5元1元纸币,每种至少一张,一共多少换法 - ?
拱幸典灵: 81种换法 一 ,每种至少一张,实际应为至少10元、5元各一张,1元的5张.共20元,剩下的80元可任意分配. 二,80元的零钱可以如下: 8张10元.1种 7张10元,5元的2、1、0张(差额为1元,下同).3种 6张10元,5元的4、3、2、1、0张.5种 5张10元,5元的6、5、4、3、2、1、0张.7种 ...... 1张10元,5元的14、13.....6、5、4、3、2、1、0张.15种 0张10元,5元的16、15、14、13.....6、5、4、3、2、1、0张.17种 三,总的换法为 1+3+5+.....+15+17=81种