兑换零钱
题目
日本的兑换零钱的机器可以用纸币兑换10日元、50日元、100日元和500日元硬币的组合,且每种硬币的数量都足够多。假设用一张纸币最多只能兑换出15枚这4种硬币,不限组合。
问题
求兑换1000日元纸币时会出现多少种组合?注意,不计硬币兑出的先后顺序。
思路
用穷举法按硬币面额从大到小,简单
@Test
public void change() {
int count = 0;
for (int i = 0; i <= 2; i++) {//500日元的硬币最多2枚
for (int j = 0; j <= 10; j++) {//100日元的硬币最多10枚
for (int k = 0; k <= 15; k++) {
for (int l = 0; l <= 15; l++) {
if ((500 * i + 100 * j + 50 * k + 10 * l == 1000) && (i + j + k + l) <= 15) {
count++;
}
}
}
}
}
System.out.println("一共会出现" + count + "种组合");
}
程序运行结果
一共会出现20种组合
上面的代码把纸币的面额写死在代码里面了,扩展性不好,可以改为递归去求解,代码如下
public static int zlCount = 0;//记录有多少种组合
public static int[] ins = {500, 100, 50, 10};//用于找零的硬币
public void change(int index, int num, int count) {
if (index == ins.length) {
return;
}
int a = ins[index];
int current = count / a;
for (int i = 0; (i <= current && i <= num); i++) {
if (count == i * a) {
zlCount++;
} else {
change(index + 1, num - i, count - a * i);//递归调用
}
}
}
测试用例
@Test
public void getChange() {
change(0, 15, 1000);
System.out.println("一共会出现" + zlCount + "种组合");
}
程序运行结果
一共会出现20种组合
总结
学会使用递归还是很有用的。