01背包
来源:互联网 发布:手机淘宝账号余额查询 编辑:程序博客网 时间:2024/06/05 06:06
今天我想讲一下01背包问题。。。
01背包是选择货物(也有其他类型,在这里我就用“货物”来代指了)重要的方法。。(指针对于每种货物只有一种)
01顾名思义,一种货物(也有可能被转化成其他,根据题意辨别)要么是0(就是不拿)要么是1(就是拿)。。
首先我们看一下背包的的本质:max1[j] = MAX(max1[j],max1[j-b[i].v]+b[i].w)意思就是你付出的代价得到的回报和你不付出代价的回报哪个更大就选择哪个(MAX是个函数表示在两个选项中选择一个最大的,max1[j]是你不付出代价的回报,max1[j-b[i].v]+b[i].w是你付出的代价
得到回报b[i]),,这里就会有同学可能问了不付出代价怎么可能有回报呢?
如果你有这个疑问你就是走入了一个误区,,,让咱们带着问题接着往
下看,,,,
我们先来做一个事例看一下:
小P寻宝记——粗心的基友
Time Limit: 1000MS Memory limit: 65536K
题目描述
这对好基友他们在经历无数的艰难险阻后,终于找到了宝藏。无奈的是这一对好基友竟然是一样的粗心,又忘记了带一个大一点的包包,可惜啊、、选择又出现了啊、、
已知包的体积是v,每种宝贝只有一个,宝贝的体积是pi,价值是wi。求出这对粗心的基友可以最多带走价值多少的宝藏。
输入
输入数据有多组。
每组第一行有两个正整数n(n <= 10000)和v(v <= 10000)分别表示n种宝贝和包的体积。
接下来n行,每行有两个正整数vi, wi。
分别表示每种宝藏的体积vi (vi<=1000),价值wi(wi<=1000)。
输出
这对基友所能带走的最多的宝藏。
示例输入
5 10
1 5
2 4
3 3
4 2
5 1
示例输出
14
代码如下:
#include
#include
#include
#define MAX_N 10020
struct baozang
{
int v; //体积(代价)
int w; //价值(回报)
}b[MAX_N];
int max1[MAX_N]; //每一个体积所对应跑下来的最大价值(最大回报)
int MAX(int x,int y) //找最大值
{
return x>y?x:y;
}
int main()
{
int n,m,i,j;
while(~scanf("%d %d",&n,&m))
{
memset(max1,0,sizeof(max1)); //把max1初始化为0
for(i=1; i<=n; i++)
{
scanf("%d %d",&b[i].v,&b[i].w); //输入占用的体积,和价值
}
for(i=1; i<=n; i++) //一个货物一个货物的排
{
for(j = m; j >= b[i].v; j--) //从背包的体积开始到该货物的体积(不能小于该货物的体积吧,不然就没意义 //了)我们再想一下为什么是从最大开始遍为什么不是从b[i].v开始到m??(以后 //再讲)01背包
{
max1[j] = MAX(max1[j],max1[j-b[i].v]+b[i].w); //01背包的核心
}
}
printf("%d\n",max1[m]); //找到最终背包体积的最大价值
}
return 0;
}
01背包是选择货物(也有其他类型,在这里我就用“货物”来代指了)重要的方法。。(指针对于每种货物只有一种)
01顾名思义,一种货物(也有可能被转化成其他,根据题意辨别)要么是0(就是不拿)要么是1(就是拿)。。
首先我们看一下背包的的本质:max1[j] = MAX(max1[j],max1[j-b[i].v]+b[i].w)意思就是你付出的代价得到的回报和你不付出代价的回报哪个更大就选择哪个(MAX是个函数表示在两个选项中选择一个最大的,max1[j]是你不付出代价的回报,max1[j-b[i].v]+b[i].w是你付出的代价
得到回报b[i]),,这里就会有同学可能问了不付出代价怎么可能有回报呢?
如果你有这个疑问你就是走入了一个误区,,,让咱们带着问题接着往
下看,,,,
我们先来做一个事例看一下:
小P寻宝记——粗心的基友
Time Limit: 1000MS Memory limit: 65536K
题目描述
这对好基友他们在经历无数的艰难险阻后,终于找到了宝藏。无奈的是这一对好基友竟然是一样的粗心,又忘记了带一个大一点的包包,可惜啊、、选择又出现了啊、、
已知包的体积是v,每种宝贝只有一个,宝贝的体积是pi,价值是wi。求出这对粗心的基友可以最多带走价值多少的宝藏。
输入
输入数据有多组。
每组第一行有两个正整数n(n <= 10000)和v(v <= 10000)分别表示n种宝贝和包的体积。
接下来n行,每行有两个正整数vi, wi。
分别表示每种宝藏的体积vi (vi<=1000),价值wi(wi<=1000)。
输出
这对基友所能带走的最多的宝藏。
示例输入
5 10
1 5
2 4
3 3
4 2
5 1
示例输出
14
代码如下:
#include
#include
#include
#define MAX_N 10020
struct baozang
{
int v; //体积(代价)
int w; //价值(回报)
}b[MAX_N];
int max1[MAX_N]; //每一个体积所对应跑下来的最大价值(最大回报)
int MAX(int x,int y) //找最大值
{
return x>y?x:y;
}
int main()
{
int n,m,i,j;
while(~scanf("%d %d",&n,&m))
{
memset(max1,0,sizeof(max1)); //把max1初始化为0
for(i=1; i<=n; i++)
{
scanf("%d %d",&b[i].v,&b[i].w); //输入占用的体积,和价值
}
for(i=1; i<=n; i++) //一个货物一个货物的排
{
for(j = m; j >= b[i].v; j--) //从背包的体积开始到该货物的体积(不能小于该货物的体积吧,不然就没意义 //了)我们再想一下为什么是从最大开始遍为什么不是从b[i].v开始到m??(以后 //再讲)01背包
{
max1[j] = MAX(max1[j],max1[j-b[i].v]+b[i].w); //01背包的核心
}
}
printf("%d\n",max1[m]); //找到最终背包体积的最大价值
}
return 0;
}
这里我们先做一个表格看一下这个代码跑的程序,,
有很多的刚接触01背包的并不能十分懂得01背包的作用,认为还不如直接贪心选择单位体积获得最大价值的方法依次放货物来的实在,,真的是这样吗??
下面我来编一组数来看看01背包和贪心的区别
输入
5 10
3 12
3 13
2 15
1 2
2 3
贪心会输出 42
01背包会输出 43
到底差在哪里呢?
哦原来贪心选了第四种物品,而01选了第五种物品啊!!自己想想为什么??
代码菜鸟,如有错误请多批评!!01背包
0 0
- 【背包专题】01背包
- 01背包,完全背包
- 01背包 完全背包
- 01背包/完全背包
- 01背包,完全背包
- 背包问题---01背包
- 背包入门--01背包
- 【背包专题】01背包
- 01背包,完全背包
- 01背包,完全背包, 多重背包
- 01背包,完全背包,多重背包
- 01背包、完全背包、多重背包详解
- 01背包,完全背包,多重背包
- 01背包、完全背包、多重背包
- 01背包、完全背包、多重背包
- 01背包、完全背包、多重背包
- 01背包、完全背包、多重背包
- 01背包、完全背包、多重背包模板
- jQuery对下拉框Select操作总结
- jquery中的图片放大镜插件--jqzoom的配置参数
- JavaScript 定义类,定义属性,定义方法的几种方式详解及分析
- 读取()txt文件中的内容与向txt文件中写入内容(覆盖重写与在末尾续写+FileOutputStream与FileWriter)
- SVN中 “containing working copy admin area is missing” 问题
- 01背包
- getsupportfragmentmanager()找不到这个方法
- SVN误删根目录导致无法安装无法卸载无法更改办法( invalid device K:\)
- STM32F4板子使用LWIP进行组播收发数据的完整过程,附代码
- 【代码笔记】iOS-评分系统(小星星)
- SQLSERVER2008R2创建分区表、转换分区表、交换数据
- leetcode记录 257. Binary Tree Paths
- 推荐一个非常有用的WordPress插件:WP2CSDNBlog
- Android Material Design之Toolbar与Palette实践