LeetCode 零钱兑换 背包问题

题目地址:
322.零钱兑换 leetcode地址
518.零钱兑换2 leetcode地址
类似题目:
123.股票问题 leetcode地址

322.零钱兑换

思路:
状态转移方程:dp[i]=min(dp[i-coin])+1 coin是coins的元素。
dp[i]表示凑成总金额i所需的最少的硬币个数。
状态转移方程的含义是:
凑成i所需的最少的硬币个数=凑成总金额(i-coin)所需的最少的硬币个数+1。
比较选出最少的dp[i]。+1表示选择了某个硬币。
比如,coins={1,2,5},那么dp[i]=min(dp[i-1],dp[i-2],dp[i-5])选出最少的硬币个数。

class Solution {
    public int coinChange(int[] coins, int amount) {
        int dp[]=new int[amount+1];//凑成i最少硬币数量
        dp[0]=0;//初始化dp
        for(int i=1;i<=amount;i++){
            int nums=-1;//如果不能凑成硬币,dp[i]=-1
            for(int j=0;j=0){
                //判断dp[tmp]>=0的原因:i-coins[j]不能凑成硬币的话继续下一次循环
                    if (nums==-1) {//第一次循环,dp[tmp]里没有值
                        nums=dp[tmp]+1;
                    }else{
                        nums=Math.min(nums,dp[tmp]+1);
                    }
                }                 
            }
            dp[i]=nums;
        }
        return dp[amount];
    }
}

518.零钱兑换

题目:给定不同面额的硬币和一个总金额。写出函数来计算可以凑成总金额的硬币组合数。假设每一种面额的硬币有无限个。

例子:
输入: amount = 5, coins = [1, 2, 5] 输出: 4
解释: 有四种方式可以凑成总金额:
5=5
5=2+2+1
5=2+1+1+1
5=1+1+1+1+1
思路:这道题可以看做完全背包问题。dp[i][v]表示最多i枚硬币组成总金额v的硬币组合数。

  1. 接下来找dp[i][v]与之前的状态的关系。之前的状态有哪些?
    这是个二维数组,状态类型有两种,一个是硬币的状态,一个是总金额的状态。
  2. 硬币的状态有几种?对于v=10的情况,coins ={1,2,5},那么可以是10枚硬币组成10元,也可以9枚硬币组成10元,也可以8枚硬币组成10 元等等,dp[i][10]表示最多i枚硬币组成10的组合数,那么dp[10][10]应该包括dp[9][10]的情况,因为最多10枚硬币组成10元的组合数一定包括最多9枚硬币组成10元的组合数。可以知道,状态转移方程大概是dp[i][v]=dp[i-1][v]+?,这样的形式。硬币的状态只与前一个硬币的状态有关。
  3. 总金额的状态有几种?根据零钱兑换1的思路,可以找一下dp[i][v]与dp[i][v-coin]的关系,即找最多i枚硬币组成总金额v的硬币组合数与最多i枚硬币组成总金额v-coin的硬币组合数的关系,举个例子,v=10,coins ={1,2,5},那么考虑最多10枚硬币组成10元的组合数和最多10枚硬币组成9元、8元、5元的组合数的关系,剩下9元、8元、5元的情况是选择硬币1、2、5之后的情况。
    所以,dp[i][v]=dp[i][v-1]+dp[i][v-2]+dp[i][v-5]+...
    可以知道,dp[i][v]=sum(dp[i][v-coin]) coin属于coins。

总结可以得到,dp[i][v]=dp[i-1][v]+dp[i][v-coin],coin属于coins。dp[i-1][v]表示第i枚硬币不选,dp[i][v-coin]表示选择第i枚硬币。

class Solution {
    public int change(int amount, int[] coins) {
        int dp[]=new int[amount+1];
        //dp[i]表示组成总金额i的组合数
        dp[0]=1;
        for(int i=0;i
LeetCode 零钱兑换 背包问题_第1张图片
代码图解

你可能感兴趣的:(LeetCode 零钱兑换 背包问题)