零钱兑换

题目地址:https://leetcode-cn.com/problems/coin-change/
题解:

一.思考步骤

1.建模

①解:代表了Xi代表了第i种硬币的个数
②目标函数:所有金币的价值为总数accout,且数量最少
③约束条件:所有的金币价值为accout

2.子问题优化

我使用k种硬币,总数为y,那么k=n,y=account的时候是原问题,
⑴:y>Vk,y>0,k>0


⑵:y=0或者k=0

⑶:y
⑷:y

3.归结公式

二.伪代码

dp[][]=new int[n+1][account+1]; 代表了k种,y总量的最小硬币数
for i=0 →n+1
   dp[i][0]=0;  //条件二
for j=1 →account+1
   dp[0][j]=∞;  //条件四
for i=1 →n+1
   for j=1 →account+1
      分成三种情况:
      1.如果j>coins[i],那么说明当前至少有一个硬币,dp[i][j]=min(dp[i][j-coins[i]]+1,dp[i-1][j]);
      2.如果j=coins[i],那么说明当前刚好够一个硬币dp[i][j]=1
      3.如果j

三.代码

public int coinChange(int[] coins, int amount) {
        int[][] dp=new int[coins.length+1][amount+1];
        for(int i=0;icoins[i-1])dp[i][j]=(dp[i][j-coins[i-1]] ==Integer.MAX_VALUE)?dp[i-1][j]:Math.min(dp[i][j-coins[i-1]]+1,dp[i-1][j]);
                //情况二
                else if(j==coins[i-1])dp[i][j]=1;
                //情况三
                else{
                   if(i==1)dp[i][j]=Integer.MAX_VALUE;
                   else dp[i][j]=dp[i-1][j];
                }
            }
        }
        if(dp[coins.length][amount]==Integer.MAX_VALUE) {
            dp[coins.length][amount]=-1;
        }
        return dp[coins.length][amount];
    }

四:其它写法

public int coinChange(int[] coins, int amount) {
        int[] dp=new int[amount+1];
        dp[0]=0;
        for(int i=1;i=0&&dp[i-coins[j]]+1
这种就是先去计算dp[i]在使用所有硬币的时候的硬币数,然后到dp[amount]的时候比较各个dp[amount-coins[i]]的关系

你可能感兴趣的:(零钱兑换)