POJ 2184 Cow Exhibition
2015-12-01 12:52
323 查看
01背包问题的变种。不过需要注意的是有两个技巧
1. 将坐标轴整体右横移,这样的话就不存在负权值了,原来的零点变为现在的区间中点。
2. 正权值即为正常的01背包,从大大小,但当负权值时,需要从小到大。不知道该如何严格证明,但是自己找个例子实践一下的话会发现是对的,这样的话本轮计算用到的值恰好是上轮的结果。
1. 将坐标轴整体右横移,这样的话就不存在负权值了,原来的零点变为现在的区间中点。
2. 正权值即为正常的01背包,从大大小,但当负权值时,需要从小到大。不知道该如何严格证明,但是自己找个例子实践一下的话会发现是对的,这样的话本轮计算用到的值恰好是上轮的结果。
#include <iostream> #include <cstdio> using namespace std; const int MAXN = 105; const int MAXV = 2 * 1e5 + 5; const int INF = 0x3f3f3f3f; int dp[MAXV], s[MAXN], f[MAXN], n; inline int max(int a, int b) { return a > b ? a : b; } int main() { int mid = 1e5; while (scanf("%d", &n) != EOF) { for (int i = 0; i < n; i++) scanf("%d%d", &s[i], &f[i]); for (int i = 0; i < MAXV; i++) dp[i] = -INF; dp[mid] = 0; for (int i = 0; i < n; i++) { if (s[i] > 0) { for (int j = MAXV; j >= s[i]; j--) dp[j] = max(dp[j], dp[j - s[i]] + f[i]); } else { for (int j = 0; j < MAXV + s[i]; j++) dp[j] = max(dp[j], dp[j - s[i]] + f[i]); } } int ans = 0; for (int i = 1e5; i <= 2 * 1e5; i++) if (dp[i] >= 0 && dp[i] + i - 1e5 > ans) ans = dp[i] + i - 1e5; printf("%d\n", ans); } }
相关文章推荐
- html中overflow以及元素的height计算问题
- 正则表达式
- Tizen web app开发示例(将2048移植到Tizen平台上)
- iOS_ARC下需要release 的情况
- Linux之kc.cfg文件参数详解
- MySQL FEDERATED引擎使用示例, 类似Oracle DBLINK
- 微信官方开源UI库-WeUI
- Maven在Windows上的安装与配置
- C#使用.net.mail配置163邮箱报错:不允许使用邮箱名称。 服务器响应为:authentication is required,smtp9,DcCowABHK4UYE11W2k6fAQ--.52196S2 1448940312
- Curses library not found. Please install appropriate package
- 100囚犯问题
- 《小亚和小信》我们的叮嘱,你一定要记住哦!
- Block的循环引用问题
- 设计模式之--适配器模式
- unity 游戏公告跑马灯循环播放的效果
- 自建IP核过程中的小问题
- 2015-12-01 SQL查询语句基础
- Codeforces Educational Round 1 C题
- Android编程之绘制文本(FontMetrics)实现方法
- 从getmemery()函数看内存管理、函数传参等一系列问题