c语言-01背包问题
01背包问题
问题:有N件物品和一个容量为V的背包。第i件物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使价值总和最大。
分析:
这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放。
用子问题定义状态:即f[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值。则其状态转移方程便是:
f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]}
这个方程非常重要,基本上所有跟背包相关的问题的方程都是由它衍生出来的。所以有必要将它详细解释一下:“将前i件物品放入容量为v的背包中”这个子问题,若只考虑第i件物品的策略(放或不放),那么就可以转化为一个只牵扯前i-1件物品的问题。如果不放第i件物品,那么问题就转化为“前i-1件物 品放入容量为v的背包中”,价值为f[i-1][v];如果放第i件物品,那么问题就转化为“前i-1件物品放入剩下的容量为v-c[i]的背包中”,此时能获得的最大价值就是f[i-1][v-c[i]]再加上通过放入第i件物品获得的价值w[i]。
优化:
以上方法的时间和空间复杂度均为O(VN),其中时间复杂度应该已经不能再优化了,但空间复杂度却可以优化到O。
先考虑上面讲的基本思路如何实现,肯定是有一个主循环i=1..N,每次算出来二维数组f[i][0..V]的所有值。那么,如果只用一个数组 f[0..V],能不能保证第i次循环结束后f[v]中表示的就是我们定义的状态f[i][v]呢?f[i][v]是由f[i-1][v]和f[i-1] [v-c[i]]两个子问题递推而来,能否保证在推f[i][v]时(也即在第i次主循环中推f[v]时)能够得到f[i-1][v]和f[i-1] [v-c[i]]的值呢?事实上,这要求在每次主循环中我们以v=V..0的顺序推f[v],这样才能保证推f[v]时f[v-c[i]]保存的是状态 f[i-1][v-c[i]]的值。伪代码如下:
for i=1..N
for v=V..0
f[v]=max{f[v],f[v-c[i]]+w[i]};
代码实现:
1 /***************01背包问题******************/ 2 #include <iostream> 3 4 using namespace std; 5 #define INF -65536 6 const int V=1000;//定义体积的最大值; 7 const int T=5;//定义商品的数目; 8 int f[V+1]; 9 //#define EMPTY 10 int w[T]={6,8,3,9,2};//商品的价值; 11 int c[T]={400,600,500,600,900};//商品的体积; 12 int package() 13 { 14 #ifdef EMPTY//可以不装满 15 for(int i=0;i<=V;i++)//条件编译,表示可以不存储满 16 { 17 f[i]=0; 18 } 19 #else//必须装满 20 f[0]=0; 21 for(int i=1;i<=V;i++)//条件编译,表示必须存储满 22 { 23 f[i]=INF; 24 } 25 #endif // EMPTY 26 for(int i=0;i<T;i++) 27 { 28 for(int v=V;v>=c[i];v--) 29 { 30 f[v]=max(f[v],f[v-c[i]]+w[i]); 31 } 32 } 33 return f[V]; 34 } 35 int main() 36 { 37 int temp; 38 temp=package(); 39 cout<<temp<<endl; 40 return 0; 41 }
说
我们看到的求最优解的背包问题题目中,事实上有两种不太相同的问法。有的题目要求“恰好装满背包”时的最优解,有的题目则并没有要求必须把背包装满。一种区别这两种问法的实现方法是在初始化的时候有所不同。
如果是第一种问法,要求恰好装满背包,那么在初始化时除了f[0]为0其它f[1..V]均设为-∞,这样就可以保证最终得到的f[N]是一种恰好装满背包的最优解。
如果并没有要求必须把背包装满,而是只希望价格尽量大,初始化时应该将f[0..V]全部设为0。
为什么呢?可以这样理解:初始化的f数组事实上就是在没有任何物品可以放入背包时的合法状态。如果要求背包恰好装满,那么此时只有容量为0的背包可能被价值为0的nothing“恰好装满”,其它容量的背包均没有合法的解,属于未定义的状态,它们的值就都应该是-∞了。如果背包并非必须被装满,那么 任何容量的背包都有一个合法解“什么都不装”,这个解的价值为0,所以初始时状态的值也就全部为0了。
明:
转载于:https://www.cnblogs.com/xiaojingang/p/3740371.html
c语言-01背包问题相关推荐
- 01背包问题c语言,0-1背包问题
[c]代码库#include #include #define MAXN 100//物品种类最大数量 int w[MAXN],V[MAXN]; int C;//最大容量 int n;//物品种类 in ...
- C语言 01背包问题
#include <stdio.h>int main(){int bagsize,num; //背包容量.物品数量scanf("%d %d",&bagsize, ...
- 0-1背包问题 动态规划c语言,详解动态规划01背包问题--JavaScript实现
一开始在接触动态规划的时候,可能会云里雾里,似乎能理解思路,但是又无法准确地表述或者把代码写出来.本篇将一步一步通过作图的方式帮助初次接触动态规划的同学来理解问题.这一篇将以经典的 01背包 问题为例 ...
- c语言贪心算法背包问题_GGTalk 中的算法知识 01背包问题
前几天 GGTalk 发了一期关于算法类的播客,主持人磊子和嘉宾 WAMaker 都分享了很有趣的算法经历.这一系列文会帮你梳理一下在这期电台中,你应该知道的知识点. 这一篇来聊聊博客中 WAMake ...
- 0-1背包问题(C语言)
任务描述 本关任务:编写一个能求解0-1背包问题的程序. 相关知识 为了完成本关任务,你需要掌握如何编写动态规划程序 有一个背包,能装载的总重量为C<300, 有 n<100个物体,每个物 ...
- 贪心算法 0-1背包c语言,贪心算法0-1背包问题(算法实验代码).pdf
. 实验三. 0-1 背包问题(贪心算法) 实验代码: #include int max(int a,int b) { if(a>b) return a; else return b; } vo ...
- c语言动态规划0-1背包,c++实现0-1背包问题完整源码(动态规划实现)
#include #define MAX_NUM 5 #define MAX_WEIGHT 10 using namespace std; //动态规划求解 int zero_one_pack(int ...
- 0-1背包问题C语言
动态规划思想编程实现0-1背包问题 #include<stdio.h> #include<stdlib.h> //用动态规划思想编程实现0-1背包问题.物品数n=5,背包容量c ...
- 分支限界法 01背包c语言,算法笔记分支限界法01背包问题
<算法笔记分支限界法01背包问题>由会员分享,可在线阅读,更多相关<算法笔记分支限界法01背包问题(12页珍藏版)>请在人人文库网上搜索. 1.问题描述给定n种物品和一背包.物 ...
最新文章
- 微信小程序APP(商超营销类)经验总结
- 我三年开发经验,从字节跳动抖音离职后,满满干货指导
- 沉得住气的程序员们!
- 可以访问本地mysql服务器的命令是_在用户访问本地MySQL服务器时,访问命令可以省略“–h localhost”。...
- 你还记得珠算的口诀吗?
- 如何开启/关闭Pages文稿上的字数统计功能?
- 吊炸天的Kubernetes微服务图形化管理工具:Kuboard,必须推荐给你!
- 基于jQuery的判断iPad、iPhone、Android是横屏还是竖屏的代码
- 百度开源的 71 个项目,你用过几个 ?
- python组合数据类型实验报告_Python程序设计实验七:组合数据类型
- python气象包_Python-Cartopy包: 地图投影
- ARCGIS基础到INVEST建模
- web批量打印pdf
- 微信小程序分享二维码扫码进入如何获取参数,小程序码进入参数为啥拿不到;
- Spring Cloud学习笔记(二)Restful理解及微服务的Restful调用
- 多重集合的排列与组合
- 创业之路 - 人脉关系 VS 人际关系
- 从科技创新到产业落地
- Mac搭建本地局域网SVN服务(Cornerstone)
- 七号信令系统在GSM中的应用