简单的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 ",ans); } return 0; }