一.01背包:

(以下均可用一维来写

即只能选择一次的物品装在一定容积的背包中。f[i][j]表示前i件物品在容积为j时的最大价值。

for(int i = 1; i <= n ;  i++){

  for(int j = v ; j >= 0 ; j--){

    if (w[i]<=j )

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

    else

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

  }

}

有需要注意的的地方:

我们看到的求最优解的背包问题题目中,事实上有两种不太相同的问法。有的题目要求“恰好装满背包”时的最优解,有的题目则并没有要求必须把背包装满。一种区别这两种问法的实现方法是在初始化的时候有所不同。
如果是第一种问法,要求恰好装满背包,那么在初始化时除了 F[0] 为 0其它F[1~V ] 均设为 -∞ ,这样就可以保证最终得到的 F[V ] 是一种恰好装满背包的最优解。
如果并没有要求必须把背包装满,而是只希望价格尽量大,初始化时应该将 F[0~V ]全部设为 0
这是为什么呢?可以这样理解:初始化的 F 数组事实上就是在没有任何物品可以放入背包时的合法状态。如果要求背包恰好装满,那么此时只有容量为 0 的背包可以在什么也不装且价值为 0 的情况下被“恰好装满”,其它容量的背包均没有合法的解,属于未定义的状态,应该被赋值为 -∞ 了。如果背包并非必须被装满,那么任何容量的背包都有一个合法解“什么都不装”,这个解的价值为 0,所以初始时状态的值也就全部为 0了。
(建议自己先画一张表,手动模拟一下状态转移的过程--这是非恰好的情况
过程建议自己亲自手模
i物品(体积,价值)\j容积 0 1 2 3 4 5
1(2,3) 0 2 3 5 6
2(1,2) 0 2 2 4 6 6
3(3,4)  0 0 2 2 2 2
4(2,2) 0 0 0 0 0 0
我自己的理解则是:
因为要求是刚好装满,所以它的容积必须在之前已经有的状态上来转移。我觉得从开始的情况来理解比较容易

if (w[i]<=j )

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

    else

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

----------------------------------------------------------------------------不得不说,想要说明白真的好难,自己理解有限,表达能力也差,只能说个半解吧

数据与代码如上,f[1][j] <-- f[0][j]。f[1][j]只能通过f[0][j]的状态转移过来,要么是直接继承f[0][j]的状态,也可以通过f[0][j-w[1]](此处即f[0][0~v-w[i]])的转移,也就是说只有当容积j恰好为w[1]的时候,才会使得f[i][j]的值能够得到有效的更新----因为初始化时只有f[0][0]的值为0,其他的均为负无穷,即使加也还是小的不得了。以此往后进行状态转移,只有当当前的容积状态的确能和之前的衔接上来才会得到有效的更新。因为当初始值不是负无穷时,受物品体积数大小的限制,并非所有的体积状态都能组合成。
而当并非恰好时,则并不需要一定要求当前的体积大小状态一定在之前已有基础(即前面的体积可以组合成的数)上才能进行有效的转移--反正都是0。

二.完全背包:

即一件物品可以无数次选择。

可以和01背包的思想结合,即将一件物品拆成多件(虽说是无数次选择,但毕竟背包容积有限)

仍然可以按照01背包的思想来解决:令f[i][v]表示前i个物品放入容积为v背包最大权值

伪代码:

for i=1..N

for v=0..V//不同于01背包①

f[v]=max(f[v],f[v-w[i]]+c[i])(v>=w[i],1<=i<=n)/ /补充:二维时还有区别----F[i, v] = max(F[i  -1, v],F[  i ,v - Ci] +Wi) ②

解释:①因为可以在之前的状态上进行转移,所以先找到之前的状态0-->n
②不同于01背包i-1这是i就是说选择放这件物品的同时也可以在这件物品的之前容积状态基础上继承。

DP之背包的更多相关文章

  1. USACO Money Systems Dp 01背包

    一道经典的Dp..01背包 定义dp[i] 为需要构造的数字为i 的所有方法数 一开始的时候是这么想的 for(i = 1; i <= N; ++i){ for(j = 1; j <= V ...

  2. 树形DP和状压DP和背包DP

    树形DP和状压DP和背包DP 树形\(DP\)和状压\(DP\)虽然在\(NOIp\)中考的不多,但是仍然是一个比较常用的算法,因此学好这两个\(DP\)也是很重要的.而背包\(DP\)虽然以前考的次 ...

  3. HDOJ(HDU).2844 Coins (DP 多重背包+二进制优化)

    HDOJ(HDU).2844 Coins (DP 多重背包+二进制优化) 题意分析 先把每种硬币按照二进制拆分好,然后做01背包即可.需要注意的是本题只需要求解可以凑出几种金钱的价格,而不需要输出种数 ...

  4. HDOJ(HDU).1059 Dividing(DP 多重背包+二进制优化)

    HDOJ(HDU).1059 Dividing(DP 多重背包+二进制优化) 题意分析 给出一系列的石头的数量,然后问石头能否被平分成为价值相等的2份.首先可以确定的是如果石头的价值总和为奇数的话,那 ...

  5. HDOJ(HDU).2191. 悼念512汶川大地震遇难同胞――珍惜现在,感恩生活 (DP 多重背包+二进制优化)

    HDOJ(HDU).2191. 悼念512汶川大地震遇难同胞――珍惜现在,感恩生活 (DP 多重背包+二进制优化) 题意分析 首先C表示测试数据的组数,然后给出经费的金额和大米的种类.接着是每袋大米的 ...

  6. HDOJ(HDU).4508 湫湫系列故事――减肥记I (DP 完全背包)

    HDOJ(HDU).4508 湫湫系列故事――减肥记I (DP 完全背包) 题意分析 裸完全背包 代码总览 #include <iostream> #include <cstdio& ...

  7. HDOJ(HDU).1284 钱币兑换问题 (DP 完全背包)

    HDOJ(HDU).1284 钱币兑换问题 (DP 完全背包) 题意分析 裸的完全背包问题 代码总览 #include <iostream> #include <cstdio> ...

  8. HDOJ(HDU).1114 Piggy-Bank (DP 完全背包)

    HDOJ(HDU).1114 Piggy-Bank (DP 完全背包) 题意分析 裸的完全背包 代码总览 #include <iostream> #include <cstdio&g ...

  9. HDOJ(HDU).3466 Dividing coins ( DP 01背包 无后效性的理解)

    HDOJ(HDU).3466 Dividing coins ( DP 01背包 无后效性的理解) 题意分析 要先排序,在做01背包,否则不满足无后效性,为什么呢? 等我理解了再补上. 代码总览 #in ...

  10. POJ.3624 Charm Bracelet(DP 01背包)

    POJ.3624 Charm Bracelet(DP 01背包) 题意分析 裸01背包 代码总览 #include <iostream> #include <cstdio> # ...

随机推荐

  1. conan使用(三)--打包只有头文件的库

    参考:https://docs.conan.io/en/latest/howtos/header_only.html?highlight=header%20only 对于只含头文件的库打包非常简单,以 ...

  2. 初识v4l2(四)-------v4l2_open、v4l2_read、v4l2_write浅析

    原文:https://blog.csdn.net/leesagacious/article/details/49995729 1.app:     open("/dev/video0&quo ...

  3. github配置密钥

    我们在githob创建项目后,本地使用git 克隆代码 需要在githob配置密钥,才可以 步骤: 下载git,进行安装,安装好后.点击桌面,右键,选择>>git  bash 在弹出的黑框 ...

  4. ubuntu安装dia

    linux下一款不错的流程图工具:dia.安装此工具:1.打开终端(快捷键:ctrl+alt+t).2.输入命令: $sudo apt-get install dia 3.提示“解压缩后会消耗掉 20 ...

  5. js正则表达式常用方法总结

    1.test()  方法用于检测一个字符串是否匹配某个模式,如果字符串中含有匹配的文本,则返回 true,否则返回 false. var patt = /e/; patt.test("The ...

  6. 【Excel】输入单引号

    首位输入:输入两个单引号 拼接输入:可以引入输入 举个例子:拼接一个SQL,values都是字符串,需要引号 =IF( OR(A2="",B2="",C2=&q ...

  7. Linux学习笔记-第5天- 坚持去做一件对的事

    坚持去做一件对的事情,并完成它.不要再给自己留遗憾了,人生已如此,是时候应该做出点改变了.

  8. 数据结构——链栈(link stack)

    /* linkStack.c */ /* 链栈 */ #include <stdio.h> #include <stdlib.h> #include <stdbool.h ...

  9. appium--Capability的配置

    前戏 desired appium的功能是配置Appium会话,他们告诉appium服务器你想要自动化的平台的程序 Desired Capability是一组设置的键值对的集合,其中键对应设置的名称, ...

  10. 一步步从零开始用 webpack 搭建一个大型项目

    开篇 很多人都或多或少使用过 webpack,但是很少有人能够系统的学习 webpack 配置,遇到错误的时候就会一脸懵,不知道从哪查起?性能优化时也不知道能做什么,网上的优化教程是不是符合自己的项目 ...