题意:给出了n头牛的智力值和幽默值,要求智力值和幽默值和的最大值;
思路:这是一个01背包问题,要么选要么不选,但由于智力值和幽默值都存在负值,那么问题就是怎么处理负值。我们只需要把数组延长一倍即可。
dp[i]代表智力为i时幽默值的最大值。
dp[j] = max(dp[j],dp[j-a[i]]+b[i]);
需要注意的是在处理负数的时候要从0开始循环;
代码:
#include <iostream> #include <cstring> #include <algorithm> #include <cstdio> using namespace std; const int inf = 0x3f3f3f3f; int a[110],b[110]; const int maxm = 200010; const int maxn = 100010; int dp[maxm]; int main() { int n; cin >> n; for(int i = 0; i < n; i++) cin >> a[i] >> b[i]; memset(dp,-inf,sizeof(dp)); dp[maxn] = 0; for(int i = 0; i < n; i++) { if(a[i]>0) { for(int j = maxm; j >= a[i]; j--) { dp[j] = max(dp[j],dp[j-a[i]]+b[i]); } } else { for(int j = 0; j < maxm+a[i]; j++) { dp[j] = max(dp[j],dp[j-a[i]]+b[i]); } } } int ans = 0; for(int i = maxn; i < maxm; i++) { if(dp[i]>0) { ans = max(ans,i-maxn+dp[i]); } } cout<<ans<<endl; return 0; }