码迷,mamicode.com
首页 > 其他好文 > 详细

POJ 2184 01背包 负数处理

时间:2020-02-26 20:39:01      阅读:103      评论:0      收藏:0      [点我收藏+]

标签:max   offset   algo   代码   注意   不能   names   ret   更新   

POJ 2184 01背包 负数处理

题意

给你n头奶牛,每头奶牛都有一个智商和情商,选出的若干头奶牛,使得智商和情商和都大于等于0的情况下,求智商总+情商总和的最大值。

解决思路

这里是选和不选的问题,01问题了。首先重量为正数时就是正常的01背包,但重量为负数时由于下标不能为负,我们需要增加数组长度。也就是把坐标0向正方向移动:0。。。offset。。。N0 - offset 之间为负数,offset - N之间为正数,dp[B]0。然后就可以进行01背包了。最后扫一遍正数区间更新一个最大值即可。

这里以智商为背包中的重量。

注意:开始我想给输入的数加上一个偏量不就行了嘛,但是这样不行,因为这样破坏了数据。

代码实现

//这里虽然题目给的数据是正负1000,但是还得大些才能过。
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<stack>
#include<queue>
#include<map>
typedef long long ll;
using namespace std;
const double esp = 1e-6;
const int inf = 0x3f3f3f3f;
const int MAXN = 2e5+7;
const int offset = 1e5;
const int rb = 2e5;
int sm[MAXN], f[MAXN], dp[MAXN];
int n;
int main()
{
    while(cin>>n)
    {
        for(int i=1; i<=n; i++){
            cin>>sm[i]>>f[i];
        }
        for(int i=0; i<=rb; i++)
            dp[i] = -inf;
        dp[offset] = 0;
        for(int i=1; i<=n; i++)
        {
            if(sm[i] >= 0)
                for(int j=rb; j>=sm[i]; j--)
                    dp[j] = max(dp[j], dp[j-sm[i]] + f[i]);
            else 
                for(int j=0; j<=rb+sm[i]; j++)
                    dp[j] = max(dp[j], dp[j-sm[i]] + f[i]);
        }
        int ans = 0;
        for(int i=offset; i<=rb; i++)
        {
            if(dp[i] >= 0)
                ans = max(ans, dp[i]+i-offset);
        }
        cout<<ans<<endl; 
    }
    return 0;
}

POJ 2184 01背包 负数处理

标签:max   offset   algo   代码   注意   不能   names   ret   更新   

原文地址:https://www.cnblogs.com/alking1001/p/12368697.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!