一.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. Ubuntu环境下载程序到STM32

    1 JLink方式 1.0 下载JLink 传送门:SEGGER官网 图1.0 下载JLink 1.2 安装JLink 双击打开下载文件:JLink_Linux_V644i_x86_64.deb 1. ...

  2. day34_8_16 MySQL数据库一

    一.数据库概念 在没有数据库时,编写项目都是使用db模拟数据库.将文件以列表或字典等存入文件夹. 但是,不同的程序员存放数据的方式都是各不相同的,而且摆放的位置都是不一样的. 如何同一数据格式,和如何 ...

  3. python27期day03:字符串详解:整型、可变数据类型和不可变数据类型、进制转换、索引、切片、步长、字符串方法、进制转换、作业题。

    1.%s: a = "我是新力,我喜欢:%s,我钟爱:%s"b = a%("开车","唱跳rap")print(b)2.整型: 整数在Pyt ...

  4. mybatis框架之多参数入参--传入Map集合

    需求:查询出指定性别和用户角色列表下的用户列表信息 实际上:mybatis在入参的时候,都是将参数封装成为map集合进行入参的,不管你是单参数入参,还是多参数入参,都是可以封装成map集合的,这是无可 ...

  5. Jmeter接口测试,怎么在下一个接口调用上一个接口的数据

    常用的两种方式,第二种容易上手1.使用正则提取器 jmeter 如何将上一个请求的结果作为下一个请求的参数——使用正则提取器(http://www.cnblogs.com/0201zcr/p/5089 ...

  6. wafer2的keng

    一.之前用wafer2开发的小程序,今天突然Error: 用户未登录过,请先使用 login() 登录? 答:改用qcloud.login, 替换掉qcloud.loginWithCode (小程序代 ...

  7. Java基础的容错

    新手会有一些常犯的过失,一般一个新手在学习Java开发的时分,往往会挑选买书去学习,首要这样的学习功率是非常差的,比如在学习html,css的时分,是彻底不必看书的.书里大多数东西你都不了解.这是新手 ...

  8. 记一次linux下安装redis, 设置redis服务, 及添加环境变量

    一. redis的安装 cd /opt                                                                                # ...

  9. Xamarin.Forms移动开发系列4 :XAML基础

    摘要 本文介绍Xamarin.Forms创建用户界面的语言:XAML基础部分. 前言 本文介绍Xamarin.Forms定义用户界面的语言:XAML. 本篇篇幅较长,主要讲述XAML语法,以及对其他基 ...

  10. day 22

    Creativity requires the courage to let go of certainties. 创新需要勇气承担不确定性.