dp背包问题
- 0-1背包
1、问题定义:
给定n种物品和背包。物品i的重量是wi,价值是vi,每种物品只有一个,背包容量为C。问:应该如何选择装入背包的物品,使得装入背包中的物品总值最大。
2、算法思路:
选择装入背包的物品时,对于物品i,只有两种选择,一种是装入,一种是不装入。定义m[i][j]表示背包容量为j,给定编号1-i号物品时,背包装入物品的最大价值。
初始化矩阵m:当只有物品1时,背包容量大于物品1的体积,放入。背包容量小于物品1的体积时,不放入。

同理,对于第i件物品,如果放入可以使得背包的价值增大且不超过背包容量,就放入,反之,不放入。

3、具体代码:
int N = ;
void knapsack(int *v, int *w, int c, int m[N+][]) {
int min = w[] > c ? c : w[];
for(int j = ; j < min; j++)
m[][j] =
for(int j = w[]; j <= c; j++)
m[][j] = v[]; for(int i = ; i <= N; i++){
min = w[i] > c ? c : w[i]
for(int j = ; j < min; j++)
m[i][j] = m[i-][j];
for(int j = w[i]; j < c; j++)
m[i][j] = m[i-][j-w[i]] + v[i] > m[i-][j] ? m[i-][j-w[i]] + v[i] : m[i-][j]
}
}
//x[N+1]存放取得最大价值的背包中放入的物品,x[i] = 1表示放入了物品i,x[i] = 0表示没有放入。
void traceback(int m[N+][], int *w, int c, int *x){
for(int i = n; i>; i++){
if(m[i][c] == m[i-][c])
x[i] == ;
else
{
x[i] = ;
c -= w[i];
}
}
x[] = m[][c] > ? :
}
- 完全背包
问题定义:
给定n种物品和背包。物品i的重量是wi,价值是vi,每种物品有无限个,背包容量为C。问:应该如何选择装入背包的物品,使得装入背包中的物品总值最大。
算法思路:
对于0-1背包问题,是否放入第i件物品取决于选取1到i-1件物品中若干件放入背包后的状态,因为每种物品只有一件,放与不放都会影响后续物品是否能放入。对于完全背包问题, 每次加入一个新的物品类别i时,都要对背包的不同容量下的价值进行更新,因为在未加入新的物品类别i时,1-i号物品已经将背包装满了。因此m[i][j]的值与m[i-1]无关。
具体算法:
#include<iostream>
#include<string.h>
#include<limits>
using namespace std;
void C_backpack(int *v, int *w, int c, int n, int *m, int *ans){
for(int i = ; i <= c; i++){
m[i] = ;
ans[i] = ;
} for(int i = ; i <= n; i++){
for(int j = w[i]; j <= c; j++){
if(m[j-w[i]] + v[i] > m[j]){
m[j] = m[j-w[i]]+v[i];
ans[j] = i;
}
}
}
}
void traceback(int *ans, int *x, int c, int *w){
while(c > ){
int id = ans[c];
x[id] ++;
c -= w[id];
}
}
int main(){
int c = , n = ;
//ans[i]表示当背包容积为j时放入的最后一个物品的编号,用来回溯得到每个物品被放入背包的个数
int ans[c+], w[n+] = {INT_MAX, , , }, v[n+] = {, , , };
int m[c+], x[n+]; //记录每个物品被放入背包的个数
memset(x , , sizeof(x));
C_backpack(v, w, c, n, m, ans);
traceback(ans, x, c, w);
for(int i = ; i <= n; i++)
cout<<x[i]<<" ";
cout<<endl;
cout<<m[c];
}
运行结果:

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 ...
- [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 ...
随机推荐
- ssh很慢的问题转子
根据网上的解决办法解决了,记录一下: 问题:ssh ***@192.*.*.* ,然后就一直卡在这个地方,很久以后才会出现让输入密码的提示 解决办法:1.关闭防火墙--chkconfig ipta ...
- CCF CSP 201503-1 图像旋转 (降维)
题目链接:http://118.190.20.162/view.page?gpid=T27 问题描述 试题编号: 201503-1 试题名称: 图像旋转 时间限制: 5.0s 内存限制: 256.0M ...
- css img 隐藏的边距
因为图片存在浏览器默认的边距,正常的情况下,增加这样的属性来消除多余的边距或者多1px的情况 img { display: block; border: node; } 但是这样的话img在父元素里设 ...
- datagridview 添加数据库数据
private void btnadd_Click(object sender, EventArgs e) { string str = @"Data Source=(localdb)\MS ...
- python 字典嵌套字典赋值异常
针对dict中 嵌套dict 出现复制异常 lists={} test=['s1','s2','s3'] data = {'value': '',} for i in range(2): lists[ ...
- JDK一键部署, 新添加进度条
JDK部署, 脚本与JDK安装包放在同一目录 然后执行 source ./jdk.sh 稍等进度条100%即可 #******************************************* ...
- Bugku-CTF之Trim的日记本(不要一次就放弃)
Day19 Trim的日记本 http://123.206.87.240:9002/ hints:不要一次就放弃
- Linux 我的常用命令记录
Linux下复制粘贴快捷键 1. 在终端下: 复制命令:Ctrl + Shift + C 组合键. 粘贴命令:Ctrl + Shift + V 组合键. 2. 在控制台下: 复制命令:Ctrl + ...
- Bigger-Mai 养成计划,Python基础巩固一
本日复习内容 Py2与Py3的区别:Py2:print()直接写字符串,不用加括号Py3:print()必须加括号,某些库改名了.还有谁不支持Py3:Twisted:具体能感知的大改动并不多 老生常谈 ...
- Git Learning2 GitHub upload
1.在自己的github上创建一个仓库 2.git remote add [name] [link] 使用git来增加一个link的别名 3.git push [linkname] [分支名] 4.g ...