• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

  • 联系
  • 订阅
  • 管理

View Post

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

posted on 2011-02-25 20:23  sysuwhj  阅读(624)  评论(1)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3