[编程题] 拼凑钱币(美团点评2017秋招)

时间限制:1秒
空间限制:32768K

给你六种面额 1、5、10、20、50、100 元的纸币,假设每种币值的数量都足够多,编写程序求组成N元(N为0~10000的非负整数)的不同组合的个数。

输入描述:
输入包括一个整数n(1 ≤ n ≤ 10000)

输出描述:
输出一个整数,表示不同的组合方案数

输入例子1:
1
输出例子1:
1

分析:
首先想到的是暴力递归方法:
1. 用0张1元货币,让【5、10、20、50、100】组成剩下的N,最终方法数记为res1。
2. 用1张1元货币,让【5、10、20、50、100】组成剩下的N - 1,最终方法数记为res2。
3. 用2张1元货币,让【5、10、20、50、100】组成剩下的N - 2,最终方法数记为res3。

N. 用N张1元货币,让【5、10、20、50、100】组成剩下的0,最终方法数记为resN。

import java.util.*;
public class Main{
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
            int aim = sc.nextInt();
            int index = 0;
            long sum = count(aim,index);
            System.out.println(sum);
        }
    }
    public static long count(int aim, int index){
        int[] arr = {1,5,10,20,50,100};
        long res = 0;
        if(index == arr.length){
            res = aim == 0 ? 1 : 0;
        } else {
            for(int i = 0; arr[index] * i <= aim; i++ ) {
                res += count(aim - arr[index] * i, index + 1);
            }
        }
        return res;
    }
}

但是这种办法耗时太长,因此需要改进
动态规划方法:

import java.util.*;
public class Main{
    public static void main(String[]args) {
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()) {
            int aim = sc.nextInt();
            int[] arr = {1, 5, 10, 20, 50, 100};
            System.out.println(count(arr,aim));
        }
    }
    public static long count(int[]arr, int aim) {
        long[][] dp = new long[arr.length][aim + 1];
        for(int i = 0; i < arr.length; i++) {
            dp[i][0] = 1;
        }
        for(int j = 1; arr[0] * j <= aim; j++) {
            dp[0][arr[0] * j] = 1;
        }
        long num = 0;
        for(int i = 1; i < arr.length; i++) {
            for(int j = 1; j <= aim; j++) {
                num = 0;
                for(int k = 0; j - arr[i] * k >= 0; k++) {
                    num += dp[i - 1][j - arr[i] * k];
                }
                dp[i][j] = num;
            }
        }
        return dp[arr.length - 1][aim];
    }
}

猜你喜欢

转载自blog.csdn.net/u013015065/article/details/78952268