題目大意就是給每個牛的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;
}