背包问题
背包问题
时间限制:
3000 ms | 内存限制:
65535 KB
难度:
3
-
描述
-
现在有很多物品(它们是可以分割的),我们知道它们每个物品的单位重量的价值v和重量w(1<=v,w<=10);如果给你一个背包它能容纳的重量为m(10<=m<=20),你所要做的就是把物品装到背包里,使背包里的物品的价值总和最大。
-
输入
-
第一行输入一个正整数n(1<=n<=5),表示有n组测试数据;
随后有n测试数据,每组测试数据的第一行有两个正整数s,m(1<=s<=10);s表示有s个物品。接下来的s行每行有两个正整数v,w。
输出
- 输出每组测试数据中背包内的物品的价值和,每次输出占一行。 样例输入
-
1 3 15 5 10 2 8 3 9
样例输出
-
65
来源
- [苗栋栋]原创 上传者
我的思路(错误的):
按照样例输入的分析的话,输入3个物品,总重量为15,设取第一个物品的重量为x,取第二个物品的重量为y,取第三个物品的和总量为z
x+y+z=15,然后按照我的思路,x*它对应的单位价值+y*它对应的单位价值+z*它对应的单位价值,然后互相博弈,求出最大值,我的代码如下
但是输出结果为75,但是样例的结果为65,这个时候我都搞不懂了,为什么呢?#include <iostream> using namespace std; int main() { int n; cin>>n; while(n--){ int s,m,z,b[3300],q=0,sum=0; cin>>s>>m; int a[s-1][2]; for(int i=0;i<s;i++){ cin>>a[i][0]; cin>>a[i][1]; } for(int i=0;i<=15;i++){ for(int j=0;j<=15-i;j++){ z=15-i-j; b[q]=a[0][0]*i+a[1][0]*j+a[2][0]*z; if(b[q]>sum) sum=b[q]; q++; } } cout<<sum<<endl; } }
我忽略了一个大问题,就是第一个商品的重量最大为10,第二个商品的重量最大为8,第三个商品的重量最大为9,这个时候,我的思路是不正确的,除了需要保证x+y+z=15以外,还需要保证x<=10,y<=8,z<=9,所以这个时候我知道我的思路是错误的!然后去网上看了别人的博客,瞬间感觉简单了许多,思路为:定义结构体,然后对重量进行排序,然后,根据重量的多少进行入库代码如下:#include <iostream> #include<algorithm> using namespace std; struct wu{ double v,w; }a[11]; //对价值进行降序排序 bool cmp(struct wu a,struct wu b){ return a.v>b.v; } int main() { int n; cin>>n; while(n--){ int s,m; cin>>s>>m; for(int i=0;i<s;i++){ cin>>a[i].v>>a[i].w; } sort(a,a+s,cmp); int sum=0; for(int i=0;i<s;i++){ if(m>=a[i].w){ sum+=a[i].v*a[i].w; m=m-a[i].w; }else if(m<a[i].w){ sum+=m*a[i].v; //重量已满,提前结束 break; } } cout<<sum<<endl; } }
这个时候我看了运行的最优的代码感觉又高大上了不少,但是我现在还没有看懂,回去和室友讨论一下#include<stdio.h> #define max(a,b) a>b?a:b int main() { int n,s,m,v,w,i,j,k; scanf("%d",&n); while(n--) { int DP[25]={0}; scanf("%d %d",&s,&m); for(i=0;i<s;i++) { scanf("%d %d",&v,&w); for(k=0;k<w;k++) for(j=m;j>0;j--) DP[j]=max(DP[j-1]+v,DP[j]); } printf("%d\n",DP[m]); } }
-
第一行输入一个正整数n(1<=n<=5),表示有n组测试数据;