LOADING

加载过慢请开启缓存 浏览器默认开启

背包问题

0-1背包:

​ 有n件物品和一个最多能背重量为w 的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品只能用一次,求解将哪些物品装入背包里物品价值总和最大。

数组含义:

​ 在一维dp数组中,dp[j]表示:容量为j的背包,所背的物品价值可以最大为dp[j]

递推公式:

dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);

遍历模板:

for(int i = 0; i < weight.size(); i++) { // 遍历物品
    for(int j = bagWeight; j >= weight[i]; j--) { // 遍历背包容量
        dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);
    }
}

倒序遍历是为了保证物品i只被放入一次!如果一旦正序遍历了,那么物品0就会被重复加入多次!

从后往前循环,每次取得状态不会和之前取得状态重合,这样每种物品就只取一次了。

完全背包:

​ 有N件物品和一个最多能背重量为W的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品都有无限个(也就是可以放入背包多次),求解将哪些物品装入背包里物品价值总和最大。

完全背包和01背包问题唯一不同的地方就是,每种物品有无限件

遍历模板:

//先遍历物品,再遍历背包
    for (int i = 0; i < weight.length; i++){ // 遍历物品
        for (int j = weight[i]; j <= bagWeight; j++){ // 遍历背包容量
            dp[j] = Math.max(dp[j], dp[j - weight[i]] + value[i]);
        }
    }
//先遍历背包,再遍历物品
for (int i = 1; i <= bagWeight; i++){ // 遍历背包容量
        for (int j = 0; j < weight.length; j++){ // 遍历物品
            if (i - weight[j] >= 0){
                dp[i] = Math.max(dp[i], dp[i - weight[j]] + value[j]);
            }
        }
    }

遍历模板(求组合数):

for (int i = 0; i < coins.size(); i++) { // 遍历物品
    for (int j = coins[i]; j <= amount; j++) { // 遍历背包容量
        dp[j] += dp[j - coins[i]];
    }
}
{% if theme.baidu_push %} {% endif %}