01背包的变形,需要注意的地方很多。
很炫的代码来自这位大神http://www.cnblogs.com/rainydays/archive/2012/07/04/2576077.html
代码很高效,边界控制很值得学习
#include<iostream>
#include<cstdio>
#include<cstring>
#define INF 0x3f3f3f3f
#define maxs 2000*100
#define shift 1000*100
using namespace std;
int dp[maxs],s[105],f[105];
int main(){
int n;
int i,j;
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d%d",&s[i],&f[i]);
for(i=0;i<maxs;i++)
dp[i]=-INF;
dp[0+shift]=0;
int l=0,r=0;
for(i=0;i<n;i++){
l=min(l,l+s[i]);
r=max(r,r+s[i]);
int step=1;
int begin=l,end=r;
if(s[i]>0){
step=-1;
swap(begin,end);
}
for(j=begin;j!=end+step;j+=step)
dp[j+shift]=max(dp[j-s[i]+shift]+f[i],dp[j+shift]);
}
int ans=0;
for(i=0;i<=r;i++)
if(dp[i+shift]>=0)
ans=max(ans,i+dp[i+shift]);
printf("%d\n",ans);
return 0;
}