POJ 2184 (01揹包)

Avalon_cc發表於2018-03-20

題意:給出了n頭牛的智力值和幽默值,要求智力值和幽默值和的最大值;

思路:這是一個01揹包問題,要麼選要麼不選,但由於智力值和幽默值都存在負值,那麼問題就是怎麼處理負值。我們只需要把陣列延長一倍即可。

dp[i]代表智力為i時幽默值的最大值。

dp[j] = max(dp[j],dp[j-a[i]]+b[i]);

需要注意的是在處理負數的時候要從0開始迴圈;

程式碼:

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>

using namespace std;
const int inf = 0x3f3f3f3f;
int a[110],b[110];
const int maxm = 200010;
const int maxn = 100010;
int dp[maxm];

int main()
{
    int n;
    cin >> n;
    for(int i = 0; i < n; i++)
        cin >> a[i] >> b[i];
    memset(dp,-inf,sizeof(dp));

    dp[maxn] = 0;
    for(int i = 0; i < n; i++)
    {
        if(a[i]>0)
        {
            for(int j = maxm; j >= a[i]; j--)
            {
                dp[j] = max(dp[j],dp[j-a[i]]+b[i]);
            }
        }
        else
        {
            for(int j = 0; j < maxm+a[i]; j++)
            {
                dp[j] = max(dp[j],dp[j-a[i]]+b[i]);
            }
        }
    }
    int ans = 0;
    for(int i = maxn; i < maxm; i++)
    {
        if(dp[i]>0)
        {
            ans = max(ans,i-maxn+dp[i]);
        }
    }
    cout<<ans<<endl;
    return 0;
}

相關文章