01背包
来源:互联网 发布:微商发图软件 编辑:程序博客网 时间:2024/04/29 07:51
01背包
背包有背包9讲,现在比较熟悉的就是01背包了,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]}
这个式子很重要,基本的思路就是这样。
1.二维:二维很方便,基本上就是一个二维VN数组,
代码如下:这里给出第一行开始填,也可以最后一行开始填
#include "stdafx.h"#include <iostream>#include <cstdio>#include <algorithm>using namespace std;struct package{ int w;//价值 int v;//容量};int main(){ package bag[100]; int n, m; int s[101][101]; cin >> n >> m; for (int i = 0; i <= n; i++) s[i][0] = 0; for (int i = 0; i <= m; i++) s[0][i] = 0; //不知道为什么,一定要把上面的两个for语句写上,否则结果就会出现问题。 for (int i = 0; i < n; i++) { cin >> bag[i + 1].v >> bag[i + 1].w; } int d = min(bag[1].v, m); for (int i = 0; i < d; i++) s[1][i] = 0; for (int i =d; i <= m; i++) s[1][i] = bag[1].w; for (int i = 2; i < n; i++) { for (int j = 0; j < bag[i].v; j++) s[i][j] = s[i - 1][j]; for (int j = bag[i].v; j <= m; j++) s[i][j] = max(s[i - 1][j], s[i - 1][j - bag[i].v] + bag[i].w); //这里需要前面的初始化。当j=beg[i].v时,就是s[i-1][0]初始化。 } if (bag[n].v > m) s[n][m] = s[n - 1][m]; else s[n][m] = max(s[n - 1][m], s[n - 1][m - bag[n].v] + bag[n].w); printf("%d\n", s[n][m]); system("pause"); return 0;}
上面的思路的是先将第一行填好,然后下一行根据上一行:
简单说就是:s[i]]n] 取决于s[i-1][n],和s[i-1][n-w]。
用过之后就就可以丢掉了,这就是为什么优化可以用一维来替换二维。
下面是一维代码:
//这里描述将二维压缩成一维背包#include "stdafx.h"#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>using namespace std;struct package{ int w; int v;};int main(){ package bag[1000]; int goal[1001]; int n, c; cin >> n >> c; for (int i = 1; i <= n; i++) { cin >> bag[i].w >> bag[i].v; } goal[0] = 0;//这里就相当于一维数组的初始化,将0行0列的初始化为0; memset(goal, 0, sizeof(goal)); for (int i = 1; i <= n; i++) { for (int j = c; j >= bag[i].w; j--) goal[j] = max(goal[j], goal[j - bag[i].w] + bag[i].v); } //这里分析为什么可以将二维压缩成一维,主要是将前面的s[i-1],[i]去掉了。 //同时必须要倒序,因为后面的数组的值是根据前面的s[j-w],s[j],如果正序 //就会先填s[j-w],导致错误 printf("%d\n", goal[c]); system("pause"); return 0;}
用一维的过程和二维差不多,就是必须要倒序,原因如上。二维就是那种随便填的。
0 0
- 【背包专题】01背包
- 01背包,完全背包
- 01背包 完全背包
- 01背包/完全背包
- 01背包,完全背包
- 背包问题---01背包
- 背包入门--01背包
- 【背包专题】01背包
- 01背包,完全背包
- 01背包,完全背包, 多重背包
- 01背包,完全背包,多重背包
- 01背包、完全背包、多重背包详解
- 01背包,完全背包,多重背包
- 01背包、完全背包、多重背包
- 01背包、完全背包、多重背包
- 01背包、完全背包、多重背包
- 01背包、完全背包、多重背包
- 01背包、完全背包、多重背包模板
- 列表
- javascript对象
- 【剑指offer】如何通过先序遍历与中序遍历重建二叉树
- 关于css清除浮动
- 为什么我在css中设定的背景图片在浏览的时候不显示?
- 01背包
- Hello CSDN
- ViewDragHelper简单使用
- TimesTen 数据库复制学习:13. 设置复制系统
- 初学者如何查阅自然语言处理(NLP)领域学术资料
- mac Certifying GDB
- Vue.js学习 Item1 --快速入门
- Python 代码风格---指南
- cygwin安装遇到的问题