币值为25分、10分、5分和1分的硬币,计算n分有几种表示方法

 

有数量不限的硬币,币值为25分、10分、5分和1分,请编写代码计算n分有几种表示法。

给定一个int n,请返回n分有几种表示法。


import java.util.Arrays;

/*
 * 我们用数组coins[i]={1,5,10,25}表示各种币值,此时可以维护一张二维表ways[i][j],
 * 其中横坐标表示前i种表示币值,j表示硬币的总值,
 * 则ways[i][j]表示能用前i种硬币来表示j分的方法数。

 当增加一种新的硬币币值时,有两种情况:

(1)不加入此种币值:ways[i][j]=ways[i-1][j];

(2)加入此种币值:加入该枚硬币之前的方法数为ways[i-1][j],那么加入该枚硬币之后构成j分的方法数也为ways[i][j-coins[i]]。

 因此当增加一种新的币值时,j分的表示方法数为ways[i][j]=ways[i-1][j]+ways[i][j-coins[i]]。
 
 */
public class Demo1 {
	
	   public static void test2(int n){
	        //纸币面额
	        int money[]={0,1,5,10,20,50,100};
	        int dp[][] = new int[6+1][n+1];
	        for (int i = 0; i < dp.length; i++) {
	        	dp[i][0] = 1 ;
			}
	        for (int i = 0; i < dp[0].length; i++) {
				dp[0][i]  = 0;
			}
	         
	        
	        for(int i = 1;i < dp.length ;++i){
	            for(int j = 1;j < dp[0].length;++j){
	            	  if (j >= money[i])
	            		  dp[i][j] = dp[i - 1][j] + dp[i][j - money[i]];
	                  else
	                      dp[i][j] = dp[i - 1][j];
	            }
	        }
	        for (int i = 0; i < dp.length; i++) {
				System.out.println(Arrays.toString(dp[i]));
			}
	        
	        System.out.println(dp[6][n]+"============");
	    }
	    public static void main(String[] args) {
	        long startTime = System.currentTimeMillis();
	        //指定200元的金额
	        test2(11);
	        long endTime = System.currentTimeMillis();
	        System.out.println("执行时间:" + (endTime - startTime) + "ms");
	    }
 
}

 

 

 

 


本代码是下面的题的答案



import java.util.Scanner;

public class Main1 {
	private static int process(int[] counts, int x) {
        int sum = 0;
        int count = 0;
        //硬币面额
        int[] a = {1, 5, 10, 20, 50, 100};

        for (int i = 0; i <= x / a[5] && i <= counts[5]; i++) {
            //100元可能出现的张数
            for (int j = 0; j <= x / a[4]&& j <= counts[4]; j++) {
                //50元可能出现的张数
                for (int k = 0; k <= x / a[3]&& k<= counts[3]; k++) {
                    //20元可能出现的张数
                    for (int l = 0; l <= x / a[2]&& l <= counts[2]; l++) {
                        //10元可能出现的张数
                        for (int m = 0; m <= x / a[1]&& m <= counts[1]; m++) {
                            //5元可能出现的张数
                            //for(int n=0;n<x/1;n++){//这步循环可省略
                            int n = x - (i * a[5] + j * a[4] + k * a[3] + l * a[2] + m * a[1]);
                            sum = i * a[5] + j * a[4] + k * a[3] + l * a[2] + m * a[1] + n * a[0];
                            if (sum == x && n >= 0 && n  <= counts[0]) {
                                System.out.println(n+" "+m+" "+l+" "+k+" "+j+" "+i);
                                 count += n+m+l+k+j+i;
                            }
                        }
                    }
                }
            }
        }
        
        return count;
    }

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int[] counts = new int[6];
		for (int i = 0; i < counts.length; i++) {
			counts[i] = sc.nextInt();
		}
		int total = sc.nextInt();
		int sum = process(counts, total);
		System.out.println(sum);
	}
}

输入和输出

6 5 4 3 2 1
11


6 1 0 0 0 0
1 2 0 0 0 0
1 0 1 0 0 0
12

 

加上时间和循环次数的判断

 


import java.util.Scanner;

public class Main1 {
    public static int process(int[] counts, int x){
    	int result = 0;
        int sum = 0;
        //符合条件的组合次数
        int count = 0;
        //循环次数
        int times = 0;
        //硬币面额
        int[] a = {1, 5, 10, 20, 50, 100};
        for (int i = 0; i <= x / a[5] && i <= counts[5]; i++) {
            //100元可能出现的张数
            for (int j = 0; j <= x / a[4]&& j <= counts[4]; j++) {
                //50元可能出现的张数
                for (int k = 0; k <= x / a[3]&& k<= counts[3]; k++) {
                    //20元可能出现的张数
                    for (int l = 0; l <= x / a[2]&& l <= counts[2]; l++) {
                        //10元可能出现的张数
                        for (int m = 0; m <= x / a[1]&& m <= counts[1]; m++) {
                            //5元可能出现的张数
                            //for(int n=0;n<x/1;n++){//这步循环可省略
                            int n = x - (i * a[5] + j * a[4] + k * a[3] + l * a[2] + m * a[1]);
                            sum = i * a[5] + j * a[4] + k * a[3] + l * a[2] + m * a[1] + n * a[0];
                            times++;
                            if (sum == x && n >= 0 && n  <= counts[0]) {
                            	count++;
                                System.out.println(n+" "+m+" "+l+" "+k+" "+j+" "+i);
                                result += n+m+l+k+j+i;
                            }
                        }
                    }
                }
            }
        }
        System.out.println("循环次数:" + times);
        System.out.println("组合数:" + count);
        return result;
    }
  

	public static void main(String[] args) {
 
		  long startTime = System.currentTimeMillis();
		  
		  Scanner sc = new Scanner(System.in);
			int[] counts = new int[6];
			for (int i = 0; i < counts.length; i++) {
				counts[i] = sc.nextInt();
			}
			int total = sc.nextInt();
			int sum = process(counts, total);
			System.out.println(sum);
			
	        long endTime = System.currentTimeMillis();
	        System.out.println("执行时间:" + (endTime - startTime) + "ms");
	}
}
6 5 4 3 2 1
11
6 1 0 0 0 0
1 2 0 0 0 0
1 0 1 0 0 0
循环次数:6
组合数:3
12
执行时间:3381ms

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值