DP---背包问题
http://www.hawstein.com/posts/dp-knapsack.html
http://www.cnblogs.com/wwwjieo0/archive/2013/04/01/2991238.html
http://blog.csdn.net/mu399/article/details/7722810
n颗宝石,体积v[i] 价值w[i] ,背包体积C
/**0-1 knapsack d(i, j)表示前i个物品装到剩余容量为j的背包中的最大重量**/
#include<cstdio>
using namespace std;
#define MAXN 1000
#define MAXC 100000 int V[MAXN], W[MAXN],x[MAXN];
int d[MAXN][MAXC]; int main(){
freopen("data.in", "r", stdin);///重定向输入流
freopen("data.out", "w", stdout);///重定向输出流
int n, C;
while(scanf("%d %d", &n, &C) != EOF){
for(int i=; i<n; ++i) scanf("%d %d", &V[i], &W[i]); for(int i=; i<=n; ++i){
for(int j=; j<=C; ++j){
d[i][j] = i== ? : d[i-][j];
if(i> && j>=V[i-])
d[i][j] =max(d[i-][j],d[i-][j-V[i-]]+W[i-]);
}
}
printf("%d\n", d[n][C]);///最终求解的最大价值 ///输出打印方案
int j = C;
for(int i=n; i>; --i){
if(d[i][j] > d[i-][j]){
x[i-] = ;
j = j - V[i-];///装入第i-1个宝石后背包能装入的体积就只剩下j - V[i-1]
}
}
for(int i=; i<n; ++i) printf("%d ", x[i]);///x[i]==1,即第i+1个放入
printf("\n");
} fclose(stdin);
fclose(stdout);
return ;
}
5 10
4 9
3 6
5 1
2 4
5 1
4 9
4 20
3 6
4 20
2 4
5 10
2 6
2 3
6 5
5 4
4 6
优化:
当一个问题找到一个放心可靠的解决方案后, 我们往往就要考虑一下是不是有优化方案了。
该算法的时间复杂度是O(nC), 即时间都花在两个for循环里了,这个应该是没办法再优化了。
再看看空间复杂度, 数组d用来保存每个状态的值,空间复杂度为O(nC);
数组V和W用来保存每个宝石的体积和价值,空间复杂度为O(n)。
程序总的空间复杂度为 O(nC),这个是可以进一步优化的。
首先,我们先把数组V和W去掉, 因为它们没有保存的必要,改为一边读入一边计算:
int v=,w=;
for(int i=; i<=n; ++i){
if(i>)
scanf("%d%d",&v,&w);
for(int j=; j<=C; ++j){
d[i][j] = i== ? : d[i-][j];
if(i> && j>=v)
d[i][j] =max(d[i-][j],d[i-][j-v]+w);
}
}
printf("%d\n", d[n][C]);///最终求解的最大价值
空间优化2,空间复杂度仅为O(C)
#include<cstdio>
#include "cstdlib"
#include "cstring"
using namespace std;
#define MAXN 1000
#define MAXC 100000 int main(){
freopen("data.in", "r", stdin);///重定向输入流
freopen("data.out", "w", stdout);///重定向输出流
int n, C;
while(scanf("%d %d", &n, &C) != EOF){ int* d = (int*)malloc((C+)*sizeof(int));
memset(d, , (C+)*sizeof(int));
int v=,w=;
for(int i=; i<=n; ++i){
if(i>)
scanf("%d%d",&v,&w);
for(int j=C; j>=; j--){
if(i> && j>=v)
d[j] =max(d[j],d[j-v]+w);
}
}
printf("%d\n", d[C]);///最终求解的最大价值 } fclose(stdin);
fclose(stdout);
return ;
}
DP---背包问题的更多相关文章
- POJ 1417 True Liars(种类并查集+dp背包问题)
题目大意: 一共有p1+p2个人,分成两组,一组p1,一组p2.给出N个条件,格式如下: x y yes表示x和y分到同一组,即同是好人或者同是坏人. x y no表示x和y分到不同组,一个为好人,一 ...
- HDU 1561 树形DP背包问题
这是自己第一道背包上树形结构问题,不是很理解这个概念的可以先看看背包九讲 自己第一次做,看了一下别人的思路,结合着对简单背包问题的求解方式自己一次AC了还是有点小激动的 题目大意是: 攻克m个城市,每 ...
- DP背包问题小总结
DP的背包问题可谓是最基础的DP了,分为01背包,完全背包,多重背包 01背包 装与不装是一个问题 01背包基本模型,背包的总体积为v,总共有n件物体,每件物品的体积为v[i],价值为w[i],每件物 ...
- DP背包问题学习笔记及系列练习题
01 背包: 01背包:在M件物品中取出若干件物品放到背包中,每件物品对应的体积v1,v2,v3,....对应的价值为w1,w2,w3,,,,,每件物品最多拿一件. 和很多DP题一样,对于每一个物品, ...
- HDU 3127 WHUgirls dp背包问题
WHUgirls Time Limit: 3000/2000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) Total ...
- 记忆搜索与动态规划——DP背包问题
题目描述 01背包问题 有n个重量和价值分别为\(w_i,v_i\)的物品.从这些物品中挑选出总重量不超过W的物品,求所有挑选方案中价值中总和的最大值. 限制条件 1 <= n <= 10 ...
- dp背包问题
0-1背包 1.问题定义: 给定n种物品和背包.物品i的重量是wi,价值是vi,每种物品只有一个,背包容量为C.问:应该如何选择装入背包的物品,使得装入背包中的物品总值最大. 2.算法思路: 选择装入 ...
- [poj 1947]树dp+背包问题
题目链接:http://poj.org/problem?id=1947 看了很多题解都是直接一遍dfs就搞定的方法,但是我实在是没看懂那个转移方程.最后在茫茫博客中终于发现了一个有逻辑的方法,但是复杂 ...
- URAL 1108 简单的树形dp背包问题
题目大意: 一颗苹果树上,每条边都对应了一个权值,最后留下包括root : 1在的含有 m 条边的子树 , 希望留下的子树中权值之和最大 这里保留m条边,我们可以看作是保留了 m + 1 个点 令dp ...
- 动态规划(DP)基础
DP基础 简单dp 背包问题 记忆化搜索 简单dp 数字三角形 给一个数字构成的三角形,求从顶端走到底部的一条路径,使得路径上的和最大(或者最小). 1 2 3 6 5 4 Example_1 7 3 ...
随机推荐
- php复制目录很浪
一不小心搞出个超级深层次文件夹 主要是因为懒,在网上随便找了段复制文件夹的代码贴上了,结果是很恐怖,一个文件夹复制到他自身里面的时候,将会产生循环嵌套文件夹,后果是,windows因为文件名太长而无法 ...
- Vue 去脚手架插件,自动加载vue文件
接上回 一些本质 本质上,去脚手架也好,读取vue文件也好,无非是维护options,每个Vue对象的初始化配置对象不触及Vue内部而言,在外部想怎么改都是可以的,只要保证options的正确,一切都 ...
- easyui combox 随便不存在的值,清空
onHidePanel: function () { var valueField = $(this).combobox("options").valueField; var va ...
- Hbase读写流程和寻址机制
写操作流程 (1) Client通过Zookeeper的调度,向RegionServer发出写数据请求,在Region中写数据. (2) 数据被写入Region的MemStore,直到MemStore ...
- 3、Java并发编程:Thread类的使用
Java并发编程:Thread类的使用 在前面2篇文章分别讲到了线程和进程的由来.以及如何在Java中怎么创建线程和进程.今天我们来学习一下Thread类,在学习Thread类之前,先介绍与线程相关知 ...
- 从C到C++ (2)
从C到C++ (2) 一. C++中增加了作用域标示符 :: 1. 用于对局部变量同名的全局变量进行访问. 2. 用于表示类成员. 二. new.delete运算符 1. ...
- java通过句柄访问对象
在Java里,任何东西都可看作对象.尽管将一切都“看作”对象,但操纵的标识符实际是指向一个对象的“句柄”(Handle),有的人将其称作一个“引用”,甚至一个“指针”. 主类型的数据成员可直接初始化, ...
- Android 序列化比对
本文转自:https://www.zybuluo.com/linux1s1s/note/91046 注:部分内容有更改 在Android中使用序列化,无非两种途经: Parcelable 和 Seri ...
- FJWC 2019 游记
FJWC 2019 游记 Day 0 春节旅游, 刚从杭州绍兴一带赶回来, 然而并没有直接飞去福州, 去了厦门再去福州, 浪费了好多时间. Day 1 酒店到学校有 \(20\) 分钟的步行路程, 感 ...
- 虚拟现实-VR-UE4-创建C++版工程
首先,创建C++版本的UE4 项目工程,我使用的是4.12.3版本,据了解,新版本后面的编译都是vs2015 所以,想要创建C++版本的工程,就需要安装vs2015 至于vs2015的安装,自己百度吧 ...