换钱的方法数-Java:动态规划方法

分享一个大牛的人工智能教程。零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来!请轻击http://www.captainbed.net

package live.every.day.ProgrammingDesign.CodingInterviewGuide.RecursionAndDynamicPrograming;

/**
 * 换钱的方法数
 *
 * 【题目】
 * 给定数组arr,arr中所有的值都为正数且不重复。每个值代表一种面值的货币,每种面值的货币可以使用任意张,再给定一个整数aim
 * 代表要找的钱数,求换钱有多少种方法。
 *
 * 【难度】
 * 中等
 *
 * 【解答】
 * 动态规划方法。生成行数为N、列数为aim+1的矩阵dp,dp[i][j]的含义是在使用arr[0..i]货币的情况下,组成钱数j有多少种方
 * 法。dp[i][j]的值求法如下:
 * 1、对于矩阵dp第一列的值dp[..][0],表示组成钱数为0的方法数,很明显是1种,也就是不使用任何货币。所以dp第一列的值统
 * 一设置为1。
 * 2、对于矩阵dp第一行的值dp[0][..],表示只能使用arr[0]这一种货币的情况下,组成钱的方法数,比如,arr[0]==5时,能组
 * 成的钱数只有0,5,10,15,...。所以,令dp[0][k*arr[0]]=1(0<=k*arr[0]<=aim,k为非负整数)。
 * 3、除第一行和第一列的其他位置,记为位置(i,j)。dp[i][j]的值是以下几个值的累加。
 * 完全不用arr[i]货币,只使用arr[0..i-1]货币时,方法数为dp[i-1][j]。
 * 用1张arr[i]货币,剩下的钱用arr[0..i-1]货币组成时,方法数为dp[i-1][j-arr[i]]。
 * 用2张arr[i]货币,剩下的钱用arr[0..i-1]货币组成时,方法数为dp[i-1][j-2*arr[i]]。
 * ......
 * 用k张arr[i]货币,剩下的钱用arr[0..i-1]货币组成时,方法数为dp[i-1][j-k*arr[i]]。j-k*arr[i]>=0,k为非负整数。
 * 4、最终dp[N-1][aim]的值就是最终结果。
 * 具体过程请参看如下代码中的coins3方法。
 *
 * @author Created by LiveEveryDay
 */
public class ChangeMoneyMethodNumberSolution3 {

    public static int coins3(int[] arr, int aim) {
        if (arr == null || arr.length == 0 || aim < 0) {
            return 0;
        }
        int[][] dp = new int[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;
        }
        int 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];
    }

    public static void main(String[] args) {
        int[] arr = {2, 5, 3};
        int aim = 10;
        System.out.printf("The method number is: %d", coins3(arr, aim));
    }

}

// ------ Output ------
/*
The method number is: 4
*/

你可能感兴趣的:(#,Coding,Interview,Guide,换钱的方法数,动态规划方法)