Loading

[USACO03FALL]Cow Exhibition G 背包优化

贝西有权选择让哪些奶牛参加展览。由于负的智商或情商会造成负面效果,所以贝西不希望出展奶牛的智商之和小于零,或情商之和小于零。

满足这两个条件下,她希望出展奶牛的智商与情商之和越大越好,请帮助贝西求出这个最大值。

• 第一行:单个整数N,1 ≤ N ≤ 400

• 第二行到第N + 1 行:第i + 1 行有两个整数:Si 和Fi,表示第i 头奶牛的智商和情商,−1000 ≤ Si; Fi ≤ 1000

 

每次决策都是选与不选,从而考虑01背包模型。

状态:dp i ,j 表示 前 i 头牛,智商为 j 时的最大情商

阶段: 第i头牛

决策 : max(dp[i][j], dp[i - 1][j - iq[i] ]+ eq[i])

这里需要注意的是:

1.智商或者情商可能出现负数,此时只需全体加M

2.初始化时由于智商情商可能出现负数,初始化时要为-INF

3.如果遇到负数的iq,那么只要正序讨论就行了,就相当于正常情况了

int readint() {
    int x = 0, f = 1; char ch = getchar();
    while (ch < '0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
    while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
    return x * f;
}

ll readll() {
    ll x = 0, f = 1; char ch = getchar();
    while (ch < '0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
    while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
    return x * f;
}

void Put(int x)  {
    if (x > 9) Put(x / 10);
    putchar(x % 10 + '0');
}


const int M = 400000;

int dp[2 * M + 5];
int iq[M];
int eq[M];

int main() {
    int n;
    n = readint();
    for (int i = 0; i < n; i++) iq[i] = readint(), eq[i] = readint();
    memset(dp, -0x3f, sizeof dp);
    dp[M] = 0;
    for (int i = 0; i < n; i++) {
        if (iq[i] >= 0) for (int j = 2 * M; j >= iq[i]; j--) dp[j] = max(dp[j], dp[j - iq[i]] + eq[i]);
        else for (int j = 0; j <= 2 * M + iq[i]; j++) dp[j] = max(dp[j], dp[j - iq[i]] + eq[i]);
    }
    int ans = 0;
    for (int i = M; i <= 2 * M; i++) if (dp[i] > 0) ans = max(ans, dp[i] + i - M);
    Put(ans);
}

 

posted @ 2020-07-31 10:02  MQFLLY  阅读(170)  评论(0编辑  收藏  举报