思路:
一眼看去只是普通的 01背包,然而数据范围让人无法下手。
之前我们考虑前 i i 件物品装入容量为 v v 的背包所能获得的最大价值,换位思考一下,我们考虑前 i i 件物品组成价值为 w w 的最小体积,于是这道题就可以解出来啦~
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int w[510],v[510],dp[5050];
int main()
{
int t,n,m;
int i,j,k;
int minn;
cin>>t;
while(t--)
{
memset(dp,0x3f,sizeof(dp));
int sum=0;
dp[0]=0; //注意这步不能丢,不然出错
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
{
scanf("%d%d",&w[i],&v[i]);
sum+=v[i];
}
for(i=1;i<=n;i++)
{
for(j=sum;j>=v[i];j--)
{
dp[j]=min(dp[j],dp[j-v[i]]+w[i]);
}
}
for(i=sum;i>=0;i--)
{
if(dp[i]<=m)
{
// cout<<dp[i]<<endl;
cout<<i<<endl;
break;
}
}
}
return 0;
}