1. 程式人生 > >我理解的01揹包(裸包)

我理解的01揹包(裸包)

這一個星期以來,被揹包問題搞得稀裡糊塗。不過還是有收穫。

對於一個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 ] ,達不到狀態轉移效果。

          另附:漫畫動態規劃