我理解的01揹包(裸包)
阿新 • • 發佈:2018-12-29
這一個星期以來,被揹包問題搞得稀裡糊塗。不過還是有收穫。
對於一個01揹包問題(01揹包是在M件物品取出若干件放在空間為W的揹包裡,每件物品的體積為C1,C2,…,Cn,與之相對應的價值為W1,W2,…,Wn.求解將那些物品裝入揹包可使總價值最大。)我的理解如下:
首先二維陣列:
for(int i = 0; i < n; i++) { for(int j = 0; j <= W; j++) {
//主要是狀態轉移方程
if(j < w[i])
{ dp[i+1][j] = dp[i][j]; //不夠取的情況 }else { dp[i+1][j] =max{dp[i][j], dp[i][j-w[i]]+v[i]}; //夠取的情況,以最大值決定取還是不取 } } }
一維陣列
memset(f,0,sizeof(f)); for(int i=1;i<=n;i++)
{ scanf("%d%d",&V,&W); for(int j = C; j >= 0 ; j-- )//注意逆序,看註釋 if(j >= V) f[j] = max ( f[j] , f[j-V] + W ); }
重點來了:
一 : f [ j ] 表示剩餘空間為 j 時所能裝的最大價值,而不是已經裝的物品的價值
二 : 最讓我迷惑的一點,當 i=1 時 f [ j ] 表示什麼?
實際上 ,當 i = 1 時說明只有一個物品可選,即使後面還有物品(因為此時只考慮 i = 1 的情況),即使空間再大隻能選一個。
還有就是。初始化時 i=0 時,陣列 f 全部初始化為 0 。
三: 逆序,因為是一維陣列,所以要儲存類似於f[ i -1 ] [ j ]的效果只能逆序;否則順序會導致f[ i ] [ j ] 覆蓋f[ i -1 ] [ j ] ,達不到狀態轉移效果。
另附:漫畫動態規劃