SDNU-1539. Do you like Hot Dog ?(背包问题:价值超大,重量小)
SDNU-1539. Do you like Hot Dog ?
Description
Given a set of n hot dog, each with a price p[i] and a happy value v[i], determine a way to choose the items into a knapsack so that the total price is less than or equal to a given limit P and the total happy value is as large as possible. Find the maximum total happy value. (Note that each item can be only chosen once).
Input
The first line contains the integer T indicating to the number of test cases.
For each test case, the first line contains the integers n and P.
Following n lines provide the information of each item.
The ith line contains the price p[i] and the happy value v[i] of the ith item respectively.
1<=numberoftestcases<=10
1<=n<=500
1<=P,w[i]<=1000000000
1<=v[1]+v[2]+...+v[n]<=5000
All the inputs are integers.
Output
For each test case, output the maximum value.
Sample Input
1
5 15
12 4
2 2
1 1
4 10
1 2
Sample Output
15
题意就是普通背包的题意,就是给的数据范围有些大。
一开始用普通的做法,然后一直RE,后来看学长的题解,发现了他是求价值为多少时的最小体积,我用一维优化了一下:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
int v[1005]/*价值*/,w[1005]/*体积*/,f[5005];//价值最大为5000
int main()
{
int t;
cin>>t;
while(t--)
{
fill(f,f+5005,INF);//取最小要都弄成正无穷,一开始因为这个一直错。。。
f[0]=0;
int V,n;
scanf("%d%d",&n,&V);
for (int i=1;i<=n;i++)
scanf("%d%d",&w[i],&v[i]);
for (int i=1;i<=n;i++)
for (int j=5001;j>=v[i];j--)
//虽然不知道他给的价值的和最大是多少(可以求),但是给出了价值上限为5000,可以利用一下,也可以求出,提高解题的范围
f[j]=min(f[j],f[j-v[i]]+w[i]);
//记住在同价值下,求得体积越小,价值也就越大
int ans=0;
for (int i=1;i<=5000;i++)//找到最大价值&&小于V的,然后输出。
if (f[i]<=V)
ans=i;
printf("%d\n",ans);
}
return 0;
}