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