程式碼隨想錄演算法訓練營第41天 | 01揹包問題 二維 、 01揹包問題 一維 、 416. 分割等和子集

YuanYF6發表於2024-06-17

如果是直接從來沒聽過揹包問題,可以先看文字講解慢慢了解 這是幹什麼的。
如果做過揹包類問題,可以先看影片,很多內容,是自己平時沒有考慮到位的。
揹包問題,力扣上沒有原題,大家先了解理論,今天就安排一道具體題目。

詳細布置

01揹包問題 二維
https://programmercarl.com/揹包理論基礎01揹包-1.html
影片講解:https://www.bilibili.com/video/BV1cg411g7Y6

二維比較好理解
function testWeightBagProblem (weight, value, size) {
    const dp = new Array(weight.length).fill(0).map(()=>new Array(size+1).fill(0));
    for (i=weight[0];i<=size;i++) {
        dp[0][i] = value[0];
    }

    for (let i=1;i<weight.length;i++) {
        for (let j=0;j<=size;j++) {
            if (j<weight[i]) {
                dp[i][j] = dp[i-1][j];
            } else {
                dp[i][j] = Math.max(dp[i-1][j], dp[i-1][j-weight[i]]+value[i]);
            }
        }
    }
    console.table(dp)
    return dp[weight.length-1][size]
}
``

 01揹包問題 一維 
https://programmercarl.com/%E8%83%8C%E5%8C%85%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%8001%E8%83%8C%E5%8C%85-2.html  
影片講解:https://www.bilibili.com/video/BV1BU4y177kY  

一維難理解,主要理解為什麼要從後遍歷,因為從前遍歷有可能會把前面的物品新增多次
從二維陣列推導公式來看一維陣列,dp[i]的值需要依靠上一組陣列的dp[i-1]的值,如果從前往後遍歷,就會有問題
另外j為什麼要大於等於wight[i],因為j是容量,如果小於,其實就完全複製就行,不用計算
function testWeightBagProblem2(wight, value, size) {
const len = wight.length;
const dp = new Array(size+1).fill(0);

for (let i=0;i<len;i++) {
    for (let j=size;j>=wight[i];j--) {
        dp[j] = Math.max(dp[j], dp[j - wight[i]]+value[i]);
    }
    console.log(dp)
}
console.log(dp)
return dp[size];

}


 416. 分割等和子集  
本題是 01揹包的應用類題目
https://programmercarl.com/0416.%E5%88%86%E5%89%B2%E7%AD%89%E5%92%8C%E5%AD%90%E9%9B%86.html    
影片講解:https://www.bilibili.com/video/BV1rt4y1N7jE

/**

  • @param {number[]} nums

  • @return {boolean}
    */
    var canPartition = function(nums) {
    let total = 0;
    for (let i=0;i<nums.length;i++) {
    total+=nums[i];
    }

    if (total%2 === 1) return false;
    const dp = new Array(total/2 + 1).fill(0);
    for (let i=0;i<nums.length;i++) {
    for(let j=total/2;j>=nums[i];j--){
    dp[j] = Math.max(dp[j], dp[j-nums[i]]+nums[i]);
    if (dp[j]===total/2) {
    return true;
    }
    }
    }

    return false;
    };

相關文章