01 揹包問題的三種寫法

2021-08-22 11:56:26 字數 1154 閱讀 8397

不妨先用最樸素的方法,針對每個物品是否放入揹包進行搜尋:

// 輸入

int n, w;

int w[max_n], v[max_n];

// 從第 i 個物品開始挑選總重小於 j 的部分

int rec(int i, int j) else if (j < w[i]) else

return res;

}void solve()

只不過,這種方法的搜尋深度是

int dp[max_n + 1][max_w + 1];  // 記憶化陣列

int rec(int i, int j)

int res;

if (i == n) else if (j < w[i]) else

// 將結果儲存在陣列中

return dp[i][j] = res;

}void solve()

對於同樣的引數,只會在第一次被呼叫到時執行遞迴部分,第二次之後都會直接返回。引數的組合不過記憶化搜尋

如果對記憶化搜尋還不是很熟練的話,可以寫成窮竭搜尋的寫法:

// 目前選擇的物品價值總和是 sum,從第 i 個物品之後的物品中挑選重量總和小於 j 的物品

int rec(int i, int j, int sum) else if (j < w[i]) else

return res;

}

在需要剪枝的情況下,可能會像這樣把各種引數都寫在函式上,但在這種下會讓記憶化搜尋難以實現,需要注意。

接下來,我們來仔細研究一下前面的演算法利用到的這個記憶化陣列。記

這樣不用寫遞迴函式,直接利用遞推式將各項的值計算出來,簡單的二重迴圈也能解決這一問題。

int dp[max_n + 1][max_w + 1];  // dp 陣列

void solve() else }}

printf("%d\n", dp[0][w]);

}

這個演算法的複雜度與前面的相同,也是動態規劃法,也就是常說

三種簡單揹包問題模板 01揹包 完全揹包 多重揹包

概念 給定n種物品的價值和重量,每種物品最多只能取一次。求出當揹包容量為m時能夠裝下的最大價值 一維的寫法,dp陣列代表的是當前狀態能夠放下的最大價值 for int i 0 i w i j dp j max dp j dp j w i v i 對於第i件物品,可以放或不放。不放 dp j dp j...

混合三種揹包問題

問題 如果將01揹包 完全揹包 多重揹包混合起來。也就是說,有的物品只可以取一次 01揹包 有的物品可以取無限次 完全揹包 有的物品可以取的次數有乙個上限 多重揹包 應該怎麼求解呢?01揹包與完全揹包的混合 考慮到在01揹包和完全揹包中最後給出的偽 只有一處不同,故如果只有兩類物品 一類物品只能取一...

混合三種揹包問題

問題 如果將01揹包 完全揹包 多重揹包混合起來。也就是說,有的物品只可以取一次 01揹包 有的物品可以取無限次 完全揹包 有的物品可以取的次數有乙個上限 多重揹包 應該怎麼求解呢?01揹包與完全揹包的混合 考慮到在01揹包和完全揹包中最後給出的偽 只有一處不同,故如果只有兩類物品 一類物品只能取一...