bone0-1背包问题
2016-05-12 20:48
246 查看
Many years ago , in Teddy’s hometown there was a man who was called “Bone Collector”. This man like to collect varies of bones , such as dog’s , cow’s , also he went to the grave …<br>The bone collector had a big bag with a volume of V ,and along his trip of
collecting there are a lot of bones , obviously , different bone has different value and different volume, now given the each bone’s value along his trip , can you calculate out the maximum of the total value the bone collector can get ?<br><center><img src=../../../data/images/C154-1003-1.jpg>
</center><br>
Input
The first line contain a integer T , the number of cases.<br>Followed by T cases , each case three lines , the first line contain two integer N , V, (N <= 1000 , V <= 1000 )representing the number of bones and the volume of his bag. And the second line contain
N integers representing the value of each bone. The third line contain N integers representing the volume of each bone.
Output
One integer per line representing the maximum of the total value (this number will be less than 2<sup>31</sup>).
Sample Input
1
5 10
1 2 3 4 5
5 4 3 2 1
Sample Output
14
题意:经典的0-1背包问题,给你物品数目以及背包的容量,下面是各个物品的价值以及容量,让你求背包能装入的最大价值状态方程 dp[i][j] = max(dp[i-1][j],dp[i-1][j-vol[i]]+val[i])表达式中各个符号的具体含义。w[i] : 第i个物体的重量;p[i] : 第i个物体的价值;c[i][m] : 前i个物体放入容量为m的背包的最大价值;c[i-1][m] : 前i-1个物体放入容量为m的背包的最大价值;c[i-1][m-w[i]] : 前i-1个物体放入容量为m-w[i]的背包的最大价值;由此可得:c[i][m]=max{c[i-1][m-w[i]]+pi , c[i-1][m]}
“将前i 件物品放入容量为v的背包中”这个子问题,若只考虑第i 件物品的策略(放或不放),那么就可以转化为一个只和前i-1件物品相关的问题。如果不放第i 件物品,那么问题就转化为“前i-1件物品放入容量为v的背包中”,价值为F[i-1; v];如果放第i 件物品,那么问题就转化为“前i-1件物品放入剩下的容量为v-Ci 的背包中”,此时能获得的最大价值就是F[i-1;v-Ci] 再加上通过放入第i 件物品获得的价值Wi。
#include<iostream>
#include<cstring>
using namespace std;
int dp[1001][1001];//前i件物品放入j容量大的背包中的最大价值
int f(int a,int b)
{
if(a>=b)
return a;
else
return b;
}
int main()
{
int va[1001],vo[1001];
int k,n,v;
cin>>k;
while(k--)
{
memset(dp,0,sizeof(dp));//对其进行初始化
cin>>n>>v;
for(int i=1;i<=n;++i)
{
cin>>va[i];
}
for(int i=1;i<=n;++i)
{
cin>>vo[i];
}
for(int i=1;i<=n;++i)
{
for(int j=0;j<=v;++j)
{
if(j<vo[i])//第i个物品无法放入
dp[i][j] = dp[i-1][j];
else
dp[i][j] = f(dp[i-1][j],dp[i-1][j-vo[i]] + va[i]);//第i个物品放入后,看看是这个物品不放入大还是放入时大,因为他放入后,前i-1个物品可能放不进去
}
}
cout<<dp
[v]<<endl;
}
return 0;
}
collecting there are a lot of bones , obviously , different bone has different value and different volume, now given the each bone’s value along his trip , can you calculate out the maximum of the total value the bone collector can get ?<br><center><img src=../../../data/images/C154-1003-1.jpg>
</center><br>
Input
The first line contain a integer T , the number of cases.<br>Followed by T cases , each case three lines , the first line contain two integer N , V, (N <= 1000 , V <= 1000 )representing the number of bones and the volume of his bag. And the second line contain
N integers representing the value of each bone. The third line contain N integers representing the volume of each bone.
Output
One integer per line representing the maximum of the total value (this number will be less than 2<sup>31</sup>).
Sample Input
1
5 10
1 2 3 4 5
5 4 3 2 1
Sample Output
14
题意:经典的0-1背包问题,给你物品数目以及背包的容量,下面是各个物品的价值以及容量,让你求背包能装入的最大价值状态方程 dp[i][j] = max(dp[i-1][j],dp[i-1][j-vol[i]]+val[i])表达式中各个符号的具体含义。w[i] : 第i个物体的重量;p[i] : 第i个物体的价值;c[i][m] : 前i个物体放入容量为m的背包的最大价值;c[i-1][m] : 前i-1个物体放入容量为m的背包的最大价值;c[i-1][m-w[i]] : 前i-1个物体放入容量为m-w[i]的背包的最大价值;由此可得:c[i][m]=max{c[i-1][m-w[i]]+pi , c[i-1][m]}
“将前i 件物品放入容量为v的背包中”这个子问题,若只考虑第i 件物品的策略(放或不放),那么就可以转化为一个只和前i-1件物品相关的问题。如果不放第i 件物品,那么问题就转化为“前i-1件物品放入容量为v的背包中”,价值为F[i-1; v];如果放第i 件物品,那么问题就转化为“前i-1件物品放入剩下的容量为v-Ci 的背包中”,此时能获得的最大价值就是F[i-1;v-Ci] 再加上通过放入第i 件物品获得的价值Wi。
#include<iostream>
#include<cstring>
using namespace std;
int dp[1001][1001];//前i件物品放入j容量大的背包中的最大价值
int f(int a,int b)
{
if(a>=b)
return a;
else
return b;
}
int main()
{
int va[1001],vo[1001];
int k,n,v;
cin>>k;
while(k--)
{
memset(dp,0,sizeof(dp));//对其进行初始化
cin>>n>>v;
for(int i=1;i<=n;++i)
{
cin>>va[i];
}
for(int i=1;i<=n;++i)
{
cin>>vo[i];
}
for(int i=1;i<=n;++i)
{
for(int j=0;j<=v;++j)
{
if(j<vo[i])//第i个物品无法放入
dp[i][j] = dp[i-1][j];
else
dp[i][j] = f(dp[i-1][j],dp[i-1][j-vo[i]] + va[i]);//第i个物品放入后,看看是这个物品不放入大还是放入时大,因为他放入后,前i-1个物品可能放不进去
}
}
cout<<dp
[v]<<endl;
}
return 0;
}
相关文章推荐
- Android 真机调试 LogCat不显示VERBOSE、DEBUG的日志信息
- windows xp vc 6.0编译最新net-snmp源码
- return to dl_resolve无需leak内存实现利用
- 【操作系统】实验三 进程调度模拟程序
- MySQL高可用方案
- HDU 3849 By Recognizing These Guys, We Find Social Networks Useful 边双连通
- 身边的素质教育
- ROS_Kinetic_04 ROS基础内容(一)
- 如何在网页中插入地图
- ROS_Kinetic_04 ROS基础内容(一)
- ROS_Kinetic_04 ROS基础内容(一)
- Fresco 专为ANDROID加载图片(简单使用)
- 周总结
- 基因治疗抗衰老首获成功:减轻肌肉质量及干细胞损耗
- CODEFORCE 672 题解(ABC)
- leetcode reconstruct-itinerary
- bzoj 3396(最小割)
- 完善短路验证时,不完美的错误信息提示
- 梦断代码阅读笔记2
- CAFFE学习笔记(三)在VS2013下生成需要的exe文件