背包变形,把s当成背包容量,f当成价值,
注意 s的值可能为负数,所以用dp0~100000存付情况,100001 ~200000存正的情况;算结果是减去-100000即可
当s为负的时候,如-3dp【10000 -3】表示-3,其对100000,100000 -1,100000 -2,产生影响所以要正向;
当 s 为整数的时候,如 4 对其产生影响的是 1 2 3,要反向
#include <iostream>
#include <stdio.h>#include <string.h>
#define maxn 200000 + 10
using namespace std;
int dp[maxn];
int fun[10010];
int smart[10010];
int main()
{
int n;
int ans;
while(scanf("%d",&n) == 1)
{
ans = 0;
for( int i = 0; i < n; i++)
scanf("%d%d",&smart[i],&fun[i]);
for( int i = 0; i < maxn ; i++)
dp[i] = -maxn;
dp[100000] = 0;
for( int i = 0; i < n; i++)
{
if(smart[i] >= 0)
{
for( int j = 200000; j >= smart[i]; j--)
dp[j] = max(dp[j], dp[j-smart[i]] + fun[i]);
}
else if( smart[i] < 0)
{
for( int j=0; j <= 200000+smart[i]; j++)
dp[j] = max(dp[j], dp[j-smart[i]] + fun[i]);
}
}
for( int i = 100000; i <= 200000; i++)
{
if(dp[i] >=0 && dp[i] + i -100000 > ans)
ans = dp[i] + i - 100000;
}
cout<<ans<<endl;
}
}