背包九讲的个人理解

主要写背包问题最优算法的个人注释,暂时先写0-1背包,完全背包,多重背包,详细基础看https://mp.csdn.net/postedit

0-1 背包:

weight 物体重量

value 物体价值

w背包可承受上限

for  i=1;i<=n;i++

    for j=w;j>=1;j--

        if(j>weight[i])

            bag[j]=max(bag[j],bag[j-wight[i]]+value[i])

        else

             bag[j]=bag[j];

注:

1 第二重循环从w开始,原因是0-1背包只有放当前物体与不放,若从1开始,一旦j开始大于当前物体重量后,前面数据可能被覆盖,后面再调用前面数据时,已经无法做到当前物体与其他物品合放,用样例模拟一下,就能明白。

2 涉及到放满背包时,bag[0],初始化为0,其他为一个负的极大值,这样,只有当物体重量刚好等于当前j,即给定j当前物品可以将其装满,就放入,后面的物体,给定j,只能刚好等于其重量或者与之前物品合放刚好等于j。

完全背包

for i=1;i<=n;i++

    for j=1;j<=weight;j++

        if j>=weight[j]

        bag[j]=max(bag[j],bag[j-weight[j]]+value[i])

        else 

         bag[j]=bag[j];

注:

     无限物体,解决方法是对于每一步能放则放,然后进行比较,比如物体重量为3时,j为3,放入比较,j为4,与体积为1放入比较,在为6之前,实际上数据还可以用上一行的,但是j为6时,要比较3个,两个该物体都不放,与放一个该物体其他空间用别的物体,还有放两个,前两者通过j为3时已经比较过,这时调用比较结果,得出最后比较结果,因此完全背包j必须从1开始,数据也需覆盖,目前理解是这样。

多重背包:

number数组存放每个物体的数量

for i=1;i<=n;i++

{

    if number[i]*weight[i]<=w

        number[i]=number[i];

    else

        number[i]=w/weight[i]

}

for i=1;i<=n;i++

{

    for k=1;k<=number[i];k*=2

    {

        for j=w;j>=1;j--

           {

                 bag[j]=max(bag[j],bag[j-weight[i]*k]+value[j]*k);
           }

    }

}

   注:

            二分,减时间,拆分后用的是0-1背包,因此,背包的第二层循环(不算二进制拆分)循环从w开始。

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