[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); }