我理解的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 ] ,达不到状态转移效果。

          另附:漫画动态规划 

猜你喜欢

转载自www.cnblogs.com/tttfu/p/10198112.html