简单的01背包,把S看体积,把F看价值,把它们变正数处理就可以了。在处理负数时,因为减一个负数相当于加一个,所以要从前往后。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <climits>
#include <string.h>
using namespace std;
int dp[200010];
struct Cow{
int s,f;
}cow[105];
int main(){
int n,positive,negative,sum;
while(scanf("%d",&n)!=EOF){
positive=negative=0;
for(int i=1;i<=n;i++){
scanf("%d%d",&cow[i].s,&cow[i].f);
if(cow[i].s<0)
negative+=(-cow[i].s);
else{
positive+=(cow[i].s);
}
}
for(int i=0;i<200010;i++)
dp[i]=INT_MIN;
int sum=negative+positive;
dp[negative]=0;
for(int i=1;i<=n;i++){
if(cow[i].s<0){
for(int p=-negative;p<=positive;p++){
if(dp[p-cow[i].s+negative]!=INT_MIN&&p-cow[i].s+negative>=0){
dp[p+negative]=max(dp[p+negative],dp[p-cow[i].s+negative]+cow[i].f);
}
}
}
else{
for(int p=positive ;p>=-negative ;p--){
if(dp[p-cow[i].s+negative]!=INT_MIN&&p-cow[i].s+negative>=0){
dp[p+negative]=max(dp[p+negative],dp[p-cow[i].s+negative]+cow[i].f);
}
}
}
}
int ans=INT_MIN;
for(int i=0 ;i<=positive ;i++){
if(dp[i+negative]>=0){
ans=max(ans,i+dp[i+negative]);
}
}
printf("%d\n",ans);
}
return 0;
}