传送门:点击打开链接
题意:背包问题。
分析:这一问题与最初的01背包问题相比,只是修改了限制条件的大小。以前求解这一问题的方法的复杂度是O(nW),对于这一问题的规模来讲就不够用了。在这个问题中,相比较重量(体积),价值的范围比较小,所以需要改变dp的对象,之前dp针对不同的重量限制计算最大的价值,这里dp针对不同的价值计算最小的重量。定义dp[i+1][j]:=前i个物品中挑选价值总和为j时总重量的的最小值。(不存在时就是一个充分大的数值INF)最终的答案就对应于dp[n][j]<=W的最大的j。
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
int t,n,c,w[105],v[105],dp[105][10005];
int main(){
cin>>t;
while(t--){
cin>>n>>c;
for(int i=0;i<n;i++) cin>>w[i]>>v[i];
for(int i=0;i<=110*n;i++) dp[0][i]=inf;
dp[0][0]=0;
for(int i=0;i<n;i++) {
for(int j=0;j<=n*100;j++) {
if(j<v[i]) dp[i+1][j]=dp[i][j];
else dp[i+1][j]=min(dp[i][j-v[i]]+w[i],dp[i][j]);
}
}
int res=0;
for(int i=0;i<=n*100;i++) if(dp[n][i]<=c) res=i;
cout<<res<<endl;
}
}