当前位置:首页 > 定制 > 正文内容

0-1背包问题和完全背包问题

gesidun3天前定制6

二者区别:0-1背包问题是说每件物品不可重复使用,而完全背包则是说每件物品可以重复使用。

先看一下0/1背包的简化版:

现有N个物品,每个物品重量为W,这些物品能否使载重量为S的背包装满(即重量和正好为S)?如过不能那能使物品重量和最重达到多少?当要装第i个物品 时,如果前i-1个物品可以使载重为 k的背包装满,那么载重为k+w

的背包就可以装满。但要注意:针对每一个物品枚举背包的载重量时如果这样正向的推导会使同一个物品用好几次,因为 k+w

可装满那k+w

+w

就可装满,但实际上是装不满的因为物品只有一个。解决这个问题很简单,只要逆向推导就OK了。给出一组具体数 据来模拟一下此过程,背包容积为21,有4个物品体积分别为8,3,12,7,输出箱子做多可占用的空间。

V                  1  2  3  4  5  6  7  8  9 10  11  12  13  14  15  16  17 18  19  20  21

添加8            0  0  0  0  0  0  0  8  8   8   8   8    8    8    8   8    8   8   8    8    8

添加3            0  0  3  3  3  3  3  8   8  8  11  11  11   11  11  11  11   11  11  11  11

添加12          0  0  3  3  3  3  3  8   8   8  11  11  11   11  11 11   11  11  11  20  20

添加7             0  0  3  3  3  3  3  8   8  10  11 11  11   11  15  15  15  18  18 20  21

代码如下:

for(int i=0;icapacity[i];j--)//V为容器的体积,capacity[i]为第i个物品的体积
      {
         if(volumn[j]

再来看一下有价值的物品放到一个容器里,如何求容器所放物品的最大值。这种情况下

存放的是容积为i的容器盛放物品的价值,还要多一个存放物品价值的数组。

代码如下:

for(int i=0;icapacity[i];j--)//V为容器的体积,capacity[i]为第i个物品的体积
      {
         if(volumn[j]

01背包求方案数:

来看一个典型的例子, 2.2.2 Sums。分析为什么它是0\1背包:将一个集合划分成两个“元素总和相等”的集合,设原集合的元素总和为sum,则划分后的集合的元素综合都为sum/2。那么我们可以把sum/2看成背包的容量,原集合中的数字看为物品的重量及价值(这里价值维度可以淡化,就像装箱问题)。则原问题转化为 “从原集合中选出n个物品,使这n个物品恰好放满容量为sum/2的背包的方案总数”。

以题目中给出的数据为例,模拟算法的过程:

V                0   1   2   3   4   5  6   7   8   9  10  11   12  13   14

放入1         1   1  0   0   0   0   0   0   0   0   0   0     0     0     0

放入2         1   1   1   1   1  0   0   0   0   0   0    0    0     0     0

放入3         1   1   1   2   1  1   1   0   0   0   0    0    0     0     0

放入4         1   1   1   2  2   2   2   2   1   1   1    0    0     0     0

放入5         1   1   1   2   2  3   3   3   3   3   3    2    2     1     1

放入6         1   1  1   2   2   3   4   4   4   5   5   5     5    4     4

放入7         1  1   1   2   2   3  4   5   5   6   7   7     8     8     8

代码如下:

/*
ID: supersnow0622
PROG: test
LANG: C++
*/
#include 
#include 
#include 
#include
using namespace std;
int main() {
    ofstream fout ("test.out");
    ifstream fin ("test.in");
    int N,f[100000];
    cin>>N;
    memset(f,0,sizeof(f));
    f[0]=f[1]=1;
    int sum=(1+N)*N/4;
    for(int i=2;i<=N;i++)
    {
     for(int j=sum;j>=0;j--)
     {
        if(j>=i)
          f[j]=f[j]+f[j-i];
     }
    }
    cout<

接下来看一下完全背包问题:

0-1添加物品时是从体积大的容器到体积小的容器添加的,这样就可以避免同一种物品重复使用了,而完全背包则是从体积小的背包开始到大的背包。其他地方和0-1背包就一样了。例题见 3.1.2

相关文章

动态规划 | 完全背包理论基础 518. 零钱兑换 II 377. 组合总和 Ⅳ 卡码网57. 爬楼梯

完全背包理论基础 每件物品都有无限个(也就是可以放入背包多次)dp 表示从下标为 0-i 的物品,每个物品可以取无限次,放进容量为j的背包,价值总和最大是多少递推公式:放物品和 不放物品,要取最大值。...

背包乱斗:福西法的宝藏

《背包乱斗:福西法的宝藏》中你需要进行合理的背包管理,这里还要不断进行自走棋战斗,你可以去购买稀有装备搭配出强力组合,利用这些玩意和其他玩家一较高下,不过搭配不好的话就只能被虐了。 《背包乱斗:福西法...

拉杆箱尺寸

常见拉杆箱尺寸: (仅供参考) 16 寸拉杆箱尺寸: 31cm*43cm*13cm 17 寸拉杆箱尺寸: 32cm*45cm*18cm 18 寸拉杆箱尺寸: 34cm*44cm*20cm 20...

行李箱密码忘了打不开?教你一个小妙招,只需30秒,就能轻松打开

你有没有过这样崩溃的瞬间:在家翻箱倒柜找行李箱密码,试了无数次,箱子却纹丝不动;或是出差在外,突然发现箱子打不开,心急如焚却毫无头绪。别担心,今天就给大家分享一个超实用的小技巧,轻松解决行李箱密码锁打...

人生第一只大牌包包怎么选?九张图看懂奢侈品大牌包包选款攻略

选择人生第一只奢侈品包包,不要追求一步到位,买现阶段最适合自己的就可以,菠萝包整理了9大奢侈品牌的经典包款合集,希望姐妹们都能选到喜欢的包包 ① 路易威登 #路易威登 法国品牌, 作为很多女...

女神必备:丝巾方巾的多样时尚打法,让你轻松提升穿搭格调

在时尚的世界里,你是否常常为如何搭配围巾、丝巾而困扰?这看似简单的配饰,实际上蕴含了无限的搭配可能。不论是出门逛街还是参加聚会,掌握几种丝巾方巾的打法让你瞬间提升气质,成为人群中的焦点。那么,究竟如何...