您的位置:首页 > 其它

nyoj 860 变形0-1背包

2015-12-07 18:57 323 查看

又见01背包

时间限制:1000 ms  |  内存限制:65535 KB

难度:3
描述
    有n个重量和价值分别为wi 和 vi 的 物品,从这些物品中选择总重量不超过 W 
的物品,求所有挑选方案中物品价值总和的最大值。
  1 <= n <=100
  1 <= wi <= 10^7
  1 <= vi <= 100
  1 <= W <= 10^9
输入多组测试数据。

每组测试数据第一行输入,n 和 W ,接下来有n行,每行输入两个数,代表第i个物品的wi 和 vi。输出满足题意的最大价值,每组测试数据占一行。样例输入
4 5
2 3
1 2
3 4
2 2

样例输出
7


分析:如果把重量当成背包,那么数组开不了那么大,仔细观察数据,发现总价值不会超过100*100,那可以把价值当成背包,背包总容量为所有物品的价值和,这样就转化为用尽量少的重量,凑出sum价值。因为总重量是W,所以在满足d[i]<=W,的前提下,让i价值尽可能大就是最后结果。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#include<vector>
using namespace std;
#define maxn 10002
#define INF 0x3f3f3f3f
const int mod=1e9+7;
int n,t;
int d[maxn],a[maxn],b[maxn];
int main()
{
//freopen("f.txt","r",stdin);
int v,w;
while(cin>>n>>t){
memset(d,INF,sizeof(d));
d[0]=0;
int sum=0;
for(int i=1;i<=n;i++)
scanf("%d %d",&a[i],&b[i]),sum+=b[i];
for(int i=1;i<=n;i++){
for(int j=sum;j>=b[i];j--){
d[j]=min(d[j],d[j-b[i]]+a[i]);
}
}
for(int i=sum;i>0;i--)
if(d[i]<=t){
printf("%d\n",i);break;
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: