01背包问题--个人最容易的理解,童叟无欺!

0-1 背包问题:给定 n 种物品和一个容量为 C 的背包,物品 i 的重量是 wi,其价值为 vi 。

问:应该如何选择装入背包的物品,使得装入背包中的物品的总价值最大?

    int v[N]={0,8,10,6,3,7,2};
    int w[N]={0,4,6,2,2,5,1};
    m[i][j]={
    {0}};
    for(int i=1;i<=n;i++)//i表示可以装进背包的数量
    {
        for(int j=1;j<=c;j++)
        {
            if(j>=w[i])//如果容量还大于物品的重量
                m[i][j]=max(m[i-1][j],m[i-1][j-w[i]]+v[i]);
            else
                m[i][j]=m[i-1][j];
        }
    }

关键代码就是上面这段;接下来请大家跟着我的思路推下来。10分钟你就能懂我理解了两小时的算法

01背包最关键的地方就在于,他要遍历所有的情况,然后在你到某个位置的时候,他前面位置已经是所有情况最优的情况了
int v[N]={0,8,10,6,3,7,2};
int w[N]={0,4,6,2,2,5,1};
首先假设我们的书包容量c是15。
第一个for:
i=1,j=1,表示可以放1件物品,容量为1,这时候背包什么都放不下。m[1][1]=0
i=1,j=2,表示可以放1件物品,容量为2,也放不下
直到i=1,j=8时,可以放入第一个物品了。
这是第一个要理解的地方,不是说你背包容量为2,就能放下标为6的那个2.是要从前面开始逐个遍历的。相当于你现在i=1,只能解锁v[1]=8那个物品在你的眼前给你放
最优的就是m[1][8]=m[0][8-8]+4=4.这时候就是代表放一件物品容量为8时的价值为4.
因为i=1.表示现在只能放一个物品,所以m[1][9]=m[0][9-8]+4=m[0][1]+4=4.这时候m[1][8]–m[1][15]最大价值都是4.

第二个for:
现在解锁到了v[1]=8,v[2]=10
i=2,j=1,表示可以放1件物品,容量为1,这时候背包什么都放不下。m[2][1]=0
也是直到i=2,j=8时。这时候j>=w[i](w[2]=10)不成立,所以进入else,m[2][8]=m[1][8]=4
到i=2,j=10.这时候j==w[2]了。m[2][10]=max(4,m[1][10-10]+10)=max(4,m[1][0]+10)=10
第二个理解的地方。容量为10.装进去之后你的背包已经没容量了。就相当于还能选一件,但是你的背包已经装不下了。所以相当于m[1][0]+10。+10是你现在这个物品放进去的价值。和之前的4比,10显然更大,所以m[2][10]=10

这样一直到第三个for,解锁了8,10,6
**##**关键点来了。最重要的地方!!
i=3,j=10时。m[3][10]=max(m[2][10],m[2][10-10]+6)=6
i=3,j=14时,m[3][14]=max(m[2][14],m[2][14-6]+2)=6
而里面的m[2][14]=max(m[1][14],m[2][8]).而这两个我们上面都推了分别为4,4.m[2][8]+2=4+2=6.
m[3][15]的时候,背包容量全开。这时候最大还是为6.也就是说三件物品时,最大价值就是6!!
所以能放前三件。最大的价值为6

到最后m[6][15]也就是最后。给你选择全部的6件物品,容量全开的情况下
m[6][15]=max(m[5][15],m[5][15-2]+1)而算这个for之前,已经算出来前5件的时候最优是9了。跟第六件各种情况max对比一下,就能得出最后结果

最后m[6][15]即为所求。

你可能感兴趣的:(算法题,算法)