解题思路:
- 普通的01背包,两个dp,dp1,dp2,令dp1j表示在选取物品i时,容量为j的背包。状态方程是:
dp1j=max(dp1j,dp1j−vi+wi)
- 令dp2表示在选取物品i时,容量为j的背包,考虑背包j正好可以装满的情况。
dp2j=max(dp2j,dp2j−vi+wi),(j−vi=0 or dp2j−vi=0)
#include<bits/stdc++.h>
using namespace std;
int main(){
int n, V;
cin>>n>>V;
vector<int> v(n+1);
vector<int> w(n+1);
vector<int> dp(V+1), dp2(V+1);
int max_w = 0;
for(int i = 1; i <= n; ++i){
cin>>v[i]>>w[i];
}
for(int i = 1; i <= n; ++i){
for(int j = V; j >= v[i]; --j){
dp[j] = max(dp[j], dp[j-v[i]] + w[i]);
if(j - v[i] == 0 || dp2[j-v[i]] != 0) dp2[j] = max(dp2[j], dp2[j-v[i]] + w[i]);
}
}
cout<<dp[V]<<endl;
cout<<dp2[V]<<endl;
return 0;
}