POJ-2184 Cow Exhibition 【題解報告】

題目鏈接

題意:每頭牛有smart值和funness值,求出在smart值的和>0&&funness值>0的情況下,smart值和funness值的總和最大。

分析:轉化成01揹包問題,每頭牛選不選就相當於每件物品選與不選,把牛的smart值看做體積,funness看做價值,則對應dp[j]表示前i件物品放入到體積爲j的揹包裏所達到的最大價值

然後對於一個0-1揹包問題,我們的遞推公式是

for(int i=W;i>=w[i];i--)
	dp[i]=dp[i-w[i]]+v[i]

在這裏有一個比較棘手的點就在於如果我們將smart值作爲體積,那麼體積會有負數,因此我們將數組開到MAX2MAX*2,大於MAX的用於表示正數,小於MAX用於表示負數,比如dp[MAX+1]dp[MAX+1]就表示smart爲1時,最大的funness的值,dp[MAX1]dp[MAX-1]就代表smart和爲1-1時,最大的funness的值。然後對每一個smart0smart\geq 0的元素,我們從右向左進行遍歷

	for (int j = sum; j >= smart[i]; j--)//正:從右向左
		if (dp[j - smart[i]] != -inf) {
			dp[j] = max(dp[j], dp[j - smart[i]] + fun[i]);
		}

需要注意的是,這裏的sum是我們爲了簡化程序所計算的所有正的smart的和,也是最大的smart,因此dpdp的索引值不會超過他,而索引值又必須大於0,因此jsmart[i]j\leq smart[i],相反對於每一個smart<0smart<0的元素,我們有

for (int j = 0; j <= sum; j++)//負:從左到右
	if (dp[j - smart[i]] != -inf) {
		dp[j] = max(dp[j], dp[j - smart[i]] + fun[i]);
	}

最後計算結束後,我們統計所有KaTeX parse error: Expected 'EOF', got '&' at position 11: i\geq MAX &̲& dp[i]>0的滿足條件的smart[i]+funness[i]smart[i]+funness[i]的最大值即可。

#define inf 0x3f3f3f3f
#define vec vector<int>
#define P pair<int,int>
#define ll long long
#define MAX 100005
int N, dp[MAX*2], F[105], T[105];
int main() {
	while (scanf("%d", &N) != EOF) {
		fill(dp, dp + 2*MAX, -inf);
		dp[MAX] = 0;
		int sum = MAX;
		for (int i = 1; i <= N; i++) {
			scanf("%d %d", &F[i], &T[i]);
			if (F[i] > 0)sum += F[i];
		}
		for (int i = 1; i <= N; i++) {
			if (F[i] >= 0) {
				for (int j = sum; j >= F[i]; j--)//正:從右向左
					if (dp[j - F[i]] != -inf) {
						dp[j] = max(dp[j], dp[j - F[i]] + T[i]);
					}
			}
			else
				for (int j = 0; j <= sum; j++)//負:從左到右
					if (dp[j - F[i]] != -inf) {
						dp[j] = max(dp[j], dp[j - F[i]] + T[i]);
					}
		}
		int ma = 0;
		for (int i = MAX; i <= sum; i++)
			if (dp[i] > 0 && dp[i] + i - MAX > ma)
				ma = dp[i] + i - MAX;
		cout << ma << endl;
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章