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;
}
浙公网安备 33010602011771号