完全背包

完全背包

此类背包问题中,我们的每种物品有无限多个,可重复选取。

类似于01背包,我们依旧需要考虑前i-1件物品的影响。

此时我们依旧可以设得二维状态

f[i][v]代表用i件物品填充为体积为v的背包得到的最大价值

依旧很容易写出状态转移方程

f[i][v]=max(f[i−1][v],f[i−1][j−k∗c[i]]+k∗w[i])

//其中k是我们需要枚举的物品件数。而我们最多选取V/c[i] 个

for(int i=1;i<=n;i++)//枚举物品

    for(int j=1;j<=V;j++)

        for(int k=1;k<=V/c[i];k++)//我们的物品最多只能放多少件。 

            {

                if(k*c[i]<=j)

                    f[i][j]=max(f[i-1][j],f[i-1][j-k*c[i]]+k*w[i]);

                else

                    f[i][j]=f[i-1][j];

                 //判断条件与01背包相同。

            }

同样地,我们去考虑一维状态

依旧设

f[i]代表体积为i的时候所能得到的最大价值

与01背包不同的是,我们可以重复选取同一件物品。

此时,我们就需要考虑到前面i-1件物品中是否有已经选取过

即,我们当前选取的物品,可能之前已经选取过。我们需要考虑之前物品对答案的贡献。因此我们需要顺序枚举。

与01背包一维的写法类似。

代码写法

for(int i=1;i<=n;i++)//枚举物品

    for(int j=c[i];j<=V;j++)//枚举体积。注意这里是顺序/

        f[j]=max(f[j],f[j-c[i]]+w[i]);//状态转移。

小结

完全背包也是类似于01背包,应该也算上是它的一种变形。

比较一般的写法是一维写法,希望大家能掌握。

例题-->p1616 疯狂的采药

posted @ 2022-03-24 09:21  心悟&&星际  阅读(34)  评论(0编辑  收藏  举报