台州 OJ 5072 Cow Exhibition 01背包
Posted 淡蓝色光
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了台州 OJ 5072 Cow Exhibition 01背包相关的知识,希望对你有一定的参考价值。
给出 n 头牛,每头牛有两个属性 smartness 和 funness ,求从所有的牛里选一些牛,使这些牛的 smartness + funness 的和最大,且 smartness 的和、funness的和都要大于零。
定义 dp[i][j] 表示前 i 头牛在 smartness 为 j 时 funness 的最大值。
dp[i][j+s[i]] = max(dp[i-1][j+s[i]], dp[i-1][j] + f[i]) s[i]、f[i] 分别表示第 i 头牛的 smartness 和 funness。
因为 smartness 可能为负,要保证在 dp 时下标要大于等于零,所以在 dp 的过程中将 j 加一个数,最后求答案时再转化回原来的数。
代码(用了两个一维数组滚动优化):
#include <iostream> #include <cstring> using namespace std; const int MAX = 2005; const int INF = 0x3f3f3f3f; const int zero = 100000; int n; int now[MAX*100], pre[MAX*100]; int s[MAX], f[MAX]; int main(){ freopen("input.txt", "r", stdin); int ans = 0, minS = 0, maxS = 0; cin >> n; for(int i=1; i<=n; i++){ cin >> s[i] >> f[i]; if(s[i] >= 0 && f[i] >= 0){ //smartness 和 funness 都大于 0 的牛一定选 ans += s[i] + f[i]; i--; n--; }else if(s[i] < 0 && f[i] < 0){ //都小于 0 的一定不选 i--; n--; } } //初始化 memset(now, -INF, sizeof(now)); now[zero] = 0; memcpy(pre, now, sizeof(now)); //DP minS = maxS = zero; // 0 变成 100000,将 smartness 为负数的情况转化为全部是正数 for(int i=1; i<=n; i++){ for(int j=minS; j<=maxS; j++){ now[j+s[i]] = max(pre[j+s[i]], pre[j] + f[i]); //smartness j+s[i] 时,funness 的最大值,考虑第 i 头牛放不放 } minS = min(minS + s[i], minS); maxS = max(maxS + s[i], maxS); memcpy(pre, now, sizeof(now)); } int maxn = 0; for(int i=zero; i<=maxS; i++){ if(now[i] >= 0){ maxn = max(maxn, (i-zero) + now[i]); //要 - zero 转化为原来的 smartness } } cout << ans + maxn; return 0; }
以上是关于台州 OJ 5072 Cow Exhibition 01背包的主要内容,如果未能解决你的问题,请参考以下文章