0-1背包

作者: laochonger | 来源:发表于2018-04-26 16:23 被阅读21次

有n种物品,————每种物品只有一个————,第i种物品的体积为Vi, 重量为Wi, 选一些物品放入容量为C的背包中,使得总物品在不超过C的情况下重量尽量大。

若如前面一般,仅凭借剩余体积这个状态,已经无法满足本题要求,因为物品具有唯一性,不能在任意时候都允许使用,为了消除混乱,需要让决策有序化。

引入“阶段”,用d(i,j)表示当前在第i层,剩余容量为j。
d(i,j) = max(d(i+1,j), d(i+1, j-V[i])+w[i])
或者 d(i,j) = max(d(i-1,j), d(i-1, j-V[i])+w[i])
通俗地说,d(i,j)表示“把第i,i+1,i+2,...,n个物品装到容量为j的背包的最大总重量”。

下面是代码,答案在d[i][C]中

for(int i = n; i >= 1; i--){
    for(int j = 0; j <= C; j++){
        d[i][j] = (i == n? 0 : d[i][j]);
        if(j >= V[i]) d[i][j] = max(d[i][j], d[i+1][j-V[i]] + W[i]);
    }
}

j可以反序(因为同一组j不关联,即非此即彼的关系),i也可以反序(但是细节上有一些不同)
另外,当i从1正向时,可以即输即用

for(int i = 1; i <= n; i++){
        scanf("%d %d", &V, &W);
    for(int j = 0; j <= C; j++){
        d[i][j] = (i == n? 0 : d[i][j]);
        if(j >= V) d[i][j] = max(d[i][j], d[i+1][j-V] + W);
    }
}

更奇妙的是,还可以把数组f变成一维滚动数组

memset(int i = 1; i <=n; i++){
        scanf("%d %d", &V, &W);
        for(int j = C; j >= 1; j++){
                if(j >= V) f[j] = max(f[i], f[j-V]+W);
        }
}

为什么可以这样呢?
1 dp的方向从上到下(为了优化读入)
2 dp的方向从右到左,即先将最右进行覆盖,而后面的操作只会用到比j更小的j-V

但是,也正由于如上原因,使得输出路径只能逆序,找到的也不是字典序最小的方案。

相关文章

  • 算法-动态规划-背包问题

    背包问题是基础的动态规划问题,包含了0-1背包,完全背包,多重背包等。 0-1背包 存在容量为 的背包 , 件体...

  • Algorithm进阶计划 -- 动态规划(下)

    经典动态规划背包问题最长子序列问题 1. 背包问题 1.1 0-1 背包问题 0-1 背包问题,描述如下: 上面...

  • 背包问题

    背包问题属于典型的动态规划问题。这里我们将详细介绍0-1背包,完全背包和多重背包问题 一、 0-1背包 有N件物品...

  • lintcode-k数和

    动态规划(确定0-1背包、完全背包、多重背包)0-1背包:每个元素要么出现,要么不出现,逆序遍历,数组定义为:前i...

  • 背包问题

    1、前言 背包问题是典型的动态规划问题,它有非常多的类型,本文讨论最常见的0-1背包问题 0-1背包问题描述:有一...

  • 动态规划

    0-1背包问题 自己实现的0-1背包问题的动态规划解法,先贴上吧,动态规划原理解释有空再写。

  • (python实现)购物单问题

    购物单问题实际上是0-1问题,在解决这个问题之前,要理解0-1背包问题。可以自己百度或者阅读我对0-1背包问题的理...

  • 动态规划入门总结(未完待续)

    首先通过求解0-1背包问题的思路演化来引出动态规划的方法。0-1背包假设我们有一个最大负重量为9的背包,同时我们有...

  • 各种背包问题

    0-1背包我比较熟悉,二维dp,通过观察方程可以优化成1维dp,不再赘述 完全背包跟0-1背包的区别是每种型号的物...

  • 编程

    今天用0-1算法,编写了背包问题!

网友评论

    本文标题:0-1背包

    本文链接:https://www.haomeiwen.com/subject/dtcmlftx.html