POJ 2184 Cow Exhibition 01揹包

題目鏈接

題目大意就是給每個牛的Si和Fi,要你選出一些牛使他們的Si和Fi的總和最大,並且他們的Si的總和不爲0,Fi也是一樣。

一開始看確實不好想,後來看了別人才知道,把Si看成花費,Fi看成價值。
不就是我們熟悉的01揹包了嗎。

但是,問題來了,題目裏有負數,所以這題難點就在這裏,你需要想一個辦法解決。

看看數據範圍。發現最大-10w,最大+10w
擴大數組,設置基準爲10w , 這樣子 0 就代表-10w ,20w就代表10w
設置dp[100000] = 100000;
這樣子就可以通過dp[x] 是否等於0來判斷是否合法

但是如果Fi是負數,就得從小開始搜。

而且20w的數據範圍,容易超時,所以一開始用l和r來識別所要用到的區間

下面貼代碼

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
using namespace std;
int dp[200005];
int mid = 100002;
int n;
int main()
{
    dp[mid] = mid;
    int c,w;
    scanf("%d",&n);
    int l = mid,r = mid;

    for(int i=0;i<n;i++){
        scanf("%d%d",&c,&w);
        l = min(l,l+c);
        r = max(r,r+c);

        if(c>0){
            for(int j=r;j>=l;j--){
                if(dp[j-c])
                dp[j] = max(dp[j],dp[j-c]+w);
            }
        }else {
            for(int j=l;j<=r;j++){
                if(dp[j-c])
                dp[j] = max(dp[j],dp[j-c]+w);
            }
        }
    }

    int res = 0;
    for(int i=mid;i<=200005;i++){
        if(dp[i]>=mid) res = max(res,dp[i]+i-mid-mid);
    }
    printf("%d\n",res);
    return 0;

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章