POJ2184

来源:互联网 发布:淘宝上的韦恩国际代购 编辑:程序博客网 时间:2024/06/01 23:15

背包变形,把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;
    }
}
0 0
原创粉丝点击