时间限制: 1 Sec 内存限制: 128 MB
题目描述
有n个重量和价值分别为wi,vi的物品。从这些物品中挑选出总重量不超过W的物品,求所有挑选方案中价值总和最大值。
输入
输入的第一行为一个整数n;第二行到第n+1行,每行两个整数,第i+1分别表示第i个物品重量wi与价值vi;最后一行有一个整数W,表示挑选出的物品总重量限制。
输出
输出只有一个整数,为所求的最大总价值。
样例输入
4
2 3
1 2
3 4
2 2
5
样例输出
7
限制条件:
1 ≤ n ≤ 100
1 ≤ w[i]≤ 10^7
1 ≤ v[i]≤ 100
1 ≤ W ≤ 10^9
题解:
由于w[i]过大,我们不能用正常的DP方程来求解。因为v[i]很小,我的想法是设计这样一个方程f[i]表示拿到价值为i的物品所需要的最小重量是多少,那么只需要对所有的f[i]判断是否超过W就好了。
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#define LiangJiaJun main
#define INF 1999122700
using namespace std;
int w[104],v[104];
int f[50004],n,limit,z;
int LiangJiaJun(){
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d%d",&w[i],&v[i]),z+=v[i];
scanf("%d",&limit);
for(int i=1;i<=50000;i++)f[i]=INF;
f[0]=0;
for(int i=1;i<=n;i++){
for(int j=z;j>=v[i];j--){
f[j]=min(f[j],f[j-v[i]]+w[i]);
}
}
for(int i=z;i>=0;i--)if(f[i]<=limit) return cout<<i<<endl,0;
return 0;
}