01背包+完全背包问题
背包问题已经有很多写得很好的博客,这里的背包问题只是一个个人学习总结,希望能够把问题说得更明白清楚易懂。
贴下背包九讲问题的优秀博客网址:
http://blog.csdn.net/pi9nc/article/details/8142876
PART1:01背包问题
题目:有N件物品,第i件物品的价值为value[i],重量为weight[i],求解将哪些物品装入背包可使价值总和最大,注意每件物品只可以装一次。
这里我们仍然以一个例子来看这个算法。
有一个能够承载10kg的小推车,商店中有如下物品:
序号 | 物品 | 重量(weight) | 价值(value) |
---|---|---|---|
1 | A | 2 | 6 |
2 | B | 2 | 3 |
3 | C | 5 | 10 |
4 | D | 4 | 7 |
5 | E | 3 | 4 |
那么我们现在研究一下,怎样才能让背包中物品的价值尽可能大。我们必须要有一个正确的思路,这是解题的关键。
设W[i][j]表示在背包可容纳重量j,只装序号不大于i的物品时,背包可装入物品的最大价值,value对应于各个物品的价值,weight对应于各个物品的重量。
算法DP公式:W[i][j] = max{如果装序号为i的物品,如果不装序号为i的物品}
=max{W[i-1][j-weight[i]]+value[i] , W[i-1][j]}
算法很简单,也很容易理解,我们不难发现算法的时间复杂度为O(N*V),空间消耗就是用了个二维数组。这里可以优化的地方就是我们不使用二维数组,使用一维数组来解决这个问题。
那么我们设一维数组为array[N]
算法:我们先对A物品分析,找出只装A物品的情况的array[N];
再添加一个B物品进行分析,我们之前已经把A物品的所有的array值都算出来了,所以可以把包含A、B物品的array[N]算出来;
同理直至到E物品,我们就算出来了结果为array[N]。
那么难点在哪里呢?难点在于每个物品最多只能装一个。
我们对只装A物品进行分析:
序号 | 物品 | 重量(weight) | 价值(value) |
---|---|---|---|
1 | A | 2 | 6 |
<—————————–我们需要将array数组初始化为零——————————>
背包可以承载的重量 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|
可装入的物品的最大价值array[i] | 0 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 |
注意:我们这个表应该从10往1生成,只有这样才能保证A物品最多只装了1个,否则结果是多个,生成的错误的表如下:
背包可以承载的重量 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|
可装入的物品的最大价值array[i] | 0 | 6 | 6 | 12 | 12 | 18 | 18 | 24 | 24 | 30 |
注意到这一点就没有别的什么问题了,现在贴上这道题的c语言代码:
#include <stdio.h>
#include <string.h>#define N 5 //物品的件数
#define W 10 //背包可容纳的最大重量
#define max(a,b) (a>b?a:b)int main()
{int i,j;int array[W+1];int weight[] = {2,2,5,4,3},value[] = {6,3,10,7,4};memset(array, 0, sizeof(array));for(i=0;i<N;i++){for(j=W;j>=weight[i];j--){array[j]=max(array[j],array[j-weight[i]]+value[i]);}}printf("%d\n",array[W]);return 0;
}
PART2:完全背包问题
题目:有N种物品,第i件物品的价值为value[i],重量为weight[i],求解将哪些物品装入背包可使价值总和最大,注意每种物品可重复装入。
如果看懂了我们上面的01背包问题,你会发现这个问题很简单,只需要我们对01背包的算法进行一丁点改变即可——就是上面说生成错误表的地方,我们就按照那种“错误”的方式生成即可得到完全背包的答案。代码该边就是在第二个循环的地方j从weight[i]到10算array数组。此处无庸赘述。
01背包+完全背包问题相关推荐
- 0-1背包 java_0-1背包问题,java的动态规划如题,代码如下public
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 0-1背包问题,java的动态规划 如题,代码如下 public class dongtaiguihua01 { public static void m ...
- python动态规划01背包_01背包问题(动态规划)python实现
在01背包问题中,在选择是否要把一个物品加到背包中.必须把该物品加进去的子问题的解与不取该物品的子问题的解进行比較,这样的方式形成的问题导致了很多重叠子问题,使用动态规划来解决.n=5是物品的数量,c ...
- 动态规划 背包问题小结 0-1背包(采药 九度第101题) 完全背包(Piggy-Bank POJ 1384) 多重背包(珍惜现在,感恩生活 九度第103题)
本小结介绍0-1背包.完全背包以及多重背包问题 记忆要点: 0-1背包:二维数组情况下,顺序遍历体积或者倒序均可以 降维情况下需倒序遍历体积 完全背包:数组降维+顺序遍历 ...
- 动态规划背包问题之01背包详解
文章目录 一.问题引入 1.什么是动态规划? 2.什么是背包问题? 3.什么是01背包? 4.背包问题怎么做? 二.例题讲解 1.题目: 2.分析 2.1 第一步:状态表示 2.2 第二步:确定状态转 ...
- 01背包 (dp专题)
01背包是在M件物品取出若干件放在空间为W的背包里,每件物品的体积为W1,W2至Wn,与之相对应的价值为P1,P2至Pn.01背包是背包问题中最简单的问题.01背包的约束条件是给定几种物品,每种物品有 ...
- 动态规划01背包算法详解
动态规划算法核心思想: 将大的问题转化为小问题进行解决. 01背包问题: 01背包是在M件物品取出若干件放在空间为W的背包里,每件物品的重量为W1,W2至Wn,与之相对应的价值为V1V2至Vn.01背 ...
- 代码随想录42——动态规划:0-1背包理论基础、0-1背包滚动数组、416分割等和子集
文章目录 1.0-1背包理论基础 1.1.概述 1.2.0-1背包 1.3.二维dp数组01背包--动规五部曲 1.4.完整测试代码 2.0-1背包滚动数组 2.1.一维滚动数组 2.2.一维dp数组 ...
- 背包问题(多重背包+0-1背包)
一:0-1背包问题 #include<iostream> #include<algorithm> #include<cstring> const int maxn= ...
- 01背包和完全背包问题
01背包和完全背包问题 posted on 2019-04-20 17:39 sofu6 阅读(...) 评论(...) 编辑 收藏 转载于:https://www.cnblogs.com/dusf/ ...
最新文章
- Angular2+ 结构型指令
- 银行业双活数据中心-F5在双活数据中心中的应用
- Java 技术篇 - 启动web服务接收浏览器请求并响应实例演示,解决socket响应浏览器显示中文乱码问题,web服务response响应设置浏览器显示字体方法
- SAP Business One
- 【机器视觉】 measure_pairs算子
- JS中的Replace方法
- 最新的CocoaPods的使用教程(一)
- Java高并发BlockingQueue重要的实现类
- iOS开发之iPhone手机轻松获取UDID的六种方式
- php 会话 写入浏览器,创建PHP会话变量会挂起我的浏览器
- 配合蓝牙打印的encoding-indexes.js文件内容:
- 如何使用Java开发QQ机器人 方法一
- UE4 各种玻璃材质制作汇总
- 杂记【1】win10 密钥模式SSH登录CentOS7
- redis底层数据结构(redis底层存储结构、源码分析)
- QT绘制区域(ROI)框(矩形框和椭圆框)
- 那些年,我们一起写过的单例模式
- Python必学知识
- xsmax无法进入dfu模式_iPhoneXSMax怎么强制重启--如何进入DFU模式
- bitmap和canvas实现图层叠加(可实现灰色遮罩)
热门文章
- gcc 指定内存地址
- 精读《维护好一个复杂项目》
- js和java那个难_javascript与java哪个难?
- FreeCAD C/C++/Python混合开发/调试方案
- JAVA毕业设计HTML5旅游网站计算机源码+lw文档+系统+调试部署+数据库
- 微信小程序 canvas 合成海报
- 朱晔和你聊Spring系列S1E11:小测Spring Cloud Kubernetes @ 阿里云K8S
- 查找——平均查找长度
- 地名用计算机符号怎么表示,写作文地名要加什么符号
- 计算机图形学期末考试嘉应学院,嘉应学院数学系模拟考试试卷一及参考答案