动态规划完全背包 fullbackpack

动态规划完全背包 fullbackpack

​ 之前我们了解了0-1背包,完全背包和0-1背包最大的差距就是完全背包每个物品有无数件,和0-1背包每个物品只有1件。

​ 0-1背包和完全背包不同的地方就是在于背包的遍历方式,0-1背包确保每个物品只可以使用一次从后往前遍历,而完全背包就完全不考虑这个问题,他就是从前往后遍历

​ 但是使用完全背包的时候一定要注意,如果我们先遍历物品在遍历背包,那么就不考虑顺序的问题如[2,1,2],[2,2,1] 他们都会看成[1,2,2]

​ 如果我们先遍历物品在遍历背包,那么他们就会被看成独立的个体,在下面的题目我们会详细讲解。

​ 接下来我们用Leetcode的几个经典的fullbackpack题目来描述。

​ 吃水不忘挖井人,感谢代码随想录。

Leetcode 518

ideas

首先我们由题意得知我们的背包最大容量为amount,那么我们初始化好DP数组。

        int[] dp = new int[amount+1];
        dp[0] = 1;  //当背包容量为0,只有一种办法,就是啥都不要

接下来我们进行DP推导,由于这个题[2,1,2],[2,2,1] 他们都会看成[1,2,2],所以我们要先遍历物品

//先遍历物品
for (int i = 0; i < coins.length; i++) {
    //在遍历背包
    for (int j = coins[i]; j <= amount; j++) {
        dp[j] += dp[j-coins[i]];
    }
}

code

class Solution {
    public int change(int amount, int[] coins) {
        int[] dp = new int[amount+1];
        dp[0] = 1;  //当背包容量为0,只有一种办法,就是啥都不要

        for (int i = 0; i < coins.length; i++) {
            for (int j = coins[i]; j <= amount; j++) {
                dp[j] += dp[j-coins[i]];
            }
        }

        return dp[amount];
    }
}

Leetcode 377

ideas

由题意我们得知我们背包最大容量为4,则我们创建dp数组和初始化。

        int[] dp = new int[target+1];
        dp[0] =1;

[2,1,2],[2,2,1] [1,2,2]他们都会看成一个独立的个体,所以我们必须先遍历背包,在遍历物品

        for (int i = 0; i < dp.length; i++) {
            for (int j = 0; j < nums.length; j++) {
                if (i-nums[i] >=0)dp[i] += dp[i - nums[j]];
            }
        }

code

    public int combinationSum4(int[] nums, int target) {
        int[] dp = new int[target+1];
        dp[0] =1;

        for (int i = 0; i < dp.length; i++) {
            for (int j = 0; j < nums.length; j++) {
                if (i-nums[i] >=0)dp[i] += dp[i - nums[j]];
            }
        }
        return dp[target];
    }

Leetcode 322

ideas

我们由题意得出最大容量为amount,由于题目要求求最小的数量,我们对dp数组进行所以哦数据为MAX,dp[0] is 0,因为如果金钱为0,就啥也没有。

        int[] dp = new int[amount+1];
        Arrays.fill(dp,Integer.MAX_VALUE);
        dp[0] = 0;

接下来进行遍历dp

        for (int i = 0; i < coins.length; i++) {
            for (int j = coins[i]; j <= amount; j++) {
                if (dp[j-coins[i]] != Integer.MAX_VALUE)
                    dp[j] = Math.min(dp[j],dp[j-coins[i]]+1);
            }
        }

如果我们dp最后一个元素为max那么直接返回-1,就说明没有匹配,

	   return dp[amount] == Integer.MAX_VALUE ? -1 : dp[amount];

code

class Solution {
    public int coinChange(int[] coins, int amount) {
        int[] dp = new int[amount+1];
        Arrays.fill(dp,Integer.MAX_VALUE);
        dp[0] = 0;

        for (int i = 0; i < coins.length; i++) {
            for (int j = coins[i]; j <= amount; j++) {
                if (dp[j-coins[i]] != Integer.MAX_VALUE)
                    dp[j] = Math.min(dp[j],dp[j-coins[i]]+1);
            }
        }

        return dp[amount] == Integer.MAX_VALUE ? -1 : dp[amount];
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哇塞大嘴好帅(DaZuiZui)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值