01 背包
来源:互联网 发布:网络水军怎么收费 编辑:程序博客网 时间:2024/05/29 09:03
01背包
问题描述:给定 n 种物品和一背包,物品 i 的重量是 wi,其价值是 vi,背包容量为 c,问应如何选择装入背包中的物品,使装入背包中的物品价值最大?
回溯法
在搜索解空间树时,只要其左儿子节点是一个可行节点,搜索就进入其左子树。当右子树中可能包含最优解时才进入右子树搜索。设 r 是当前剩余物品的价值总和;cv 是当前价值;max 是当前最优价值。当 cv + r <= max 时, 可减去右子树。
void BackTrack(int cw, int cv, int i) { if (i > n) { max = cv; return; } if (cw + w[i] <= c) BackTrack(cw + w[i], cv + v[i], i + 1); if (cv + r[i + 1] > max) BackTrack(cw, cv, i + 1);}void Init() { for (int i = n; i >= 1; i--) r[i] = r[i + 1] + v[i];}
动态规划(递推法)
正常的状态定义 d(i,j) = max{d(i+1,j), d(i+1,j-W[i]) + V[i]}
d(i,j) 表示当前在第 i 层,背包剩余容量为 j 时的最大价值和,边界是 i > n 时 d(i,j) = 0;
for (int i = n; i >= 1; i--) for (int j = 0; j <= c; j++) { d[i][j] = (i == n ? 0 : d[i+1][j]); if (j >= W[i]) d[i][j] = max(d[i][j], d[i+1][j-W[i]] + V[i]); }
对称的状态定义 f(i,j) = max{f(i-1,j), f(i-1,j-W[i]) + V[i]}
f(i,j) 表示把前 i 个物品装到容量为 j 的背包中的最大价值和,边界是 i= 0 时 f(i,j) = 0;
for (int i = 1; i <= n; i++) for (int j = 0; j <= c; j++) { f[i][j] = (i == 1 ? 0 : f[i-1][j]); if (j >= W[i]) f[i][j] = max(f[i][j], f[i-1][j-W[i]] + V[i]); }
边读边计算, 不必把 V 和 W 保存下来
for (int i = 1; i <= n; i++) { scanf("%d%d", &V, &W); for (int j = 0; j <= c; j++) { f[i][j] = (i == 1 ? 0 : f[i-1][j]); if (j >= W) f[i][j] = max(f[i][j], f[i-1][j-W] + V); }}
滚动数组, 把数组 f 变成一维的
memset(f, 0, sizeof(f));for (int i = 1; i <= n; i++) { scanf("%d%d", &V, &W); for (int j = 0; j <= c; j++) if (j >= W) f[j] = max(f[j], f[j-W] + V);}
0 0
- 【背包专题】01背包
- 01背包,完全背包
- 01背包 完全背包
- 01背包/完全背包
- 01背包,完全背包
- 背包问题---01背包
- 背包入门--01背包
- 【背包专题】01背包
- 01背包,完全背包
- 01背包,完全背包, 多重背包
- 01背包,完全背包,多重背包
- 01背包、完全背包、多重背包详解
- 01背包,完全背包,多重背包
- 01背包、完全背包、多重背包
- 01背包、完全背包、多重背包
- 01背包、完全背包、多重背包
- 01背包、完全背包、多重背包
- 01背包、完全背包、多重背包模板
- 屏幕适配全攻略(二)-- 解决方案
- Eclipse 插件安装方法
- DIY:用开源软件搭建自己的物联网
- 高精度模板1.0
- 变位词(兄弟字符串)
- 01 背包
- centos linux 服务器时间少8个小时的问题
- Linux下的find命令
- Ubuntu相关学习笔记
- 固定ip 与 路由算法
- CoreData VS Realm (2016-02-23更新)
- 网络信息安全攻防实验室 脚本关第二关
- Java垃圾回收
- App架构设计经验谈:数据层的设计