Java 硬币凑数问题

问题描述:硬币分别有面值分别为1,5, 10, 25四种面值。输入一个整数n,用这些硬币组合成数值n,问有多少种组合方式?

解法一:暴力破解,用四个for循环破解。

代码如下:


import java.util.Scanner;

public class 硬币凑数问题 {
	public static void main(String[] args){
		Scanner scanner = new Scanner(System.in);
		int n = scanner.nextInt();
		System.out.println(solve(n));
	}
	/**
	 * for循环暴力法破解
	 * @param n
	 * @return
	 */
	private static int solve(int n) {
		int sum = 0;
		for(int i=0; i<=n; i++){
			for(int j=0; j*5<=n; j++){
				for(int k=0; k*10<=n; k++){
					for(int l=0; l*25<=n; l++){
						if((i+5*j+k*10+l*25 == n)) sum++;
					}
				}
			}
		}
		return sum;
	}
}

解法二:用递推的方法实现,这个递归关键在于变量的设置,设三个变量,第一个是需要凑的数值n;第二个是一个数组表arr示硬币的面值,是固定不变的;第三个是硬币的可用范围m,也就是数组下标。当前可用的最大硬币面值是arr[m]。
分解过程是这样的将凑整数n分解为:用一个arr[m]参与组合,用2arr[m]参与组合,用3arr[m]参与组合,一直分解到iarr[m], 当ia>n时停止。
边界出口就是当m=0时,也就是只能用面值为1的硬币进行组合的时候,这时只有一种组合(剩余的数值都用面值为1的硬币来凑)。当n=0时,返回1,而不是返回0;返回0的话最终结果会比正确答案少1。因为n=0表示的情况是剩余的数值是0,也就是说上一次数值刚好是最大面值的整数倍。举个列子:假设数值是100,则刚好可以用4个25面值的硬币表示剩余值为0;这也一种组合方式。所以应该返回的值1。
这题需要注意的地方是它是多分支的分解情况,与寻常递归只有两三种分支情况不同(比如斐波那契数列求和)。所以这题需要再循环中进行递归。
递归最需要注意的地方就是分解的表达式和出口是否正确。

代码如下:


import java.util.Scanner;

public class 硬币凑数问题 {
	public static void main(String[] args){
		Scanner scanner = new Scanner(System.in);
		int n = scanner.nextInt();
		int[] a = {1,5,10,25};
		System.out.println(solve(n, a, 3));
	}
	
	private static int solve(int n, int[] a, int m) {
		int res = 0;
		if(m==0) return 1;
		if(n==0) return 1;
		for(int i=0; i*a[m]<=n; i++){
			res = res + solve(n-i*a[m], a, m-1);
		}
		return res;
	}
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

逍遥自在”

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值