poj 2184 Cow Exhibition 背包
这题想了很久,虽然知道是01背包,但加了两个约束条件后,就不知道如何做了。
直到看到解题报告才懂这题思路。先定死一个变量,求另外一个变量,得到各个结果再找出最优解。
设dp[i][v]为前i头牛给定smart为v时的最大fun值之和。就可以转化为01背包。
dp[i][v] = max(dp[i-1][v-s[i]] + f[i], dp[i-1][v])。注意由于smart可以是负的,要把smart整体加100*1000。当s[i]为负数时,从递增遍历,
#include <iostream> #include <cstdio> using namespace std; const int MAX = 100*1001*2; const int N = 105; const int INF = 1000000000; int dp[MAX]; int s[N], f[N]; int n; int main() { scanf("%d", &n); for (int i = 1; i <= n; i++) scanf("%d%d", &s[i], &f[i]); for (int i = 0; i <= 200000; i++) dp[i] = -INF; dp[100000] = 0; for (int i = 1; i <= n; i++) { if (s[i] < 0 && f[i] < 0) continue; if (s[i] > 0) { for (int v = 200000; v >= s[i]; v--) if (dp[v-s[i]] > -INF) dp[v] = max(dp[v], dp[v-s[i]] + f[i]); } else { for (int v = s[i]; v <= 200000+s[i]; v++) if (dp[v-s[i]] > -INF) dp[v] = max(dp[v], dp[v-s[i]] + f[i]); } } int ans = 0; for (int v = 100000; v <= 200000; v++) { if (dp[v] >= 0) ans = max(ans, dp[v]+v-100000); } printf("%d\n", ans); return 0; }