现在有一个容量为C的背包和N个重量和价值已知的物品. 现在要从这n个物品中挑选出一些物品, 使得选择的物品的总重量不
超过背包的容量, 且总价值最大. 此题的数据范围:
1 <= C <= 10^8(10的8次方)
1 <= N <= 100
输入描述:有多组测试数据. 第一行一个正整数T(T<=15), 表示测试数据组数.
对于每组测试数据:
第一行两个正整数N和C, 分别表示物品的数量和背包的容量.
接下来N行, 每行两个正整数w,v ,分别表示对应物品的重量和价值(1<= w <= 10^7, 1<= v <= 100)
输出描述:输出一个正整数, 表示在所选物品不超过背包容量的情况下, 能够得到的最大价值.
输入样例
1
3 10
5 10
5 10
4 12
输出样例:22
#include <iostream>
using namespace std;
const int M=105;const int INF=1e9;
int dp[M][M*100]={0};int w[M],v[M];
int Min(int a,int b)
{
if(a<=b)
return a;
else
return b;
}
void clear(int N)
{
for(int i=1;i<=N;i++)
{
w[i]=0;v[i]=0;
}
}
void cal_dp(int N,int sum,int C)
{
for(int i=1;i<=sum;i++)
dp[0][i]=INF;
for(int i=0;i<=M;i++)
dp[i][0]=0;
for(int j=1;j<=sum;j++)
{
for(int i=1;i<=N;i++)
{
if(v[i]<=j&&dp[i-1][j-v[i]]!=INF)
dp[i][j]=Min(dp[i-1][j],dp[i-1][j-v[i]]+w[i]);
else
dp[i][j]=dp[i-1][j];
}
}
for(int i=sum;i>=0;i--)
{
if(dp[N][i]<=C)
{
cout<<i<<endl;
break;
}
}
}
int main()
{
int T,N,C;cin>>T;
while(T--)
{
int sum=0;
cin>>N>>C;
for(int i=1;i<=N;i++)
{
cin>>w[i]>>v[i];
sum+=v[i];
}
cal_dp(N,sum,C);
clear(N);
}
return 0;
}
由于该重量很大,故打表会超时,考虑用价值作为参数。dp【i】【j】表示前i个物体凑成j价值的最小重量。