poj 2184--Cow Exhibition
来源:互联网 发布:网络洗钱的常见方式 编辑:程序博客网 时间:2024/05/16 05:32
有一群奶牛,每一头都有s[i], f[i]两个值。在其中找一个子集,要在保证这两个值均为非负的情况下,使s和f的总和最大。
http://poj.org/problem?id=2184
这是01背包的变形,因为有负值的存在,背包的体积为-100000~100000
我们可以将区间平移到0~200000,原点就变成了100000
在进行01背包时,dp[v] = max(dp[v], dp[v - c[i]] + w[i],要用dp[v - c[i]]更新dp[v],所以要从大到小遍历。
但当c[i] < 0时,要从小到大遍历,因为v - c[i] > v。
在遍历结果的时候要从新的原点100000开始
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int inf = 0x3f3f3f3f;int n, s[1000 + 10], f[1000 + 10], dp[200000 + 10];int main(){ scanf("%d", &n); for(int i=0; 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=0; i<n; i++){ if(s[i] > 0){ for(int j=200000; j>=s[i]; j--) dp[j] = max(dp[j], dp[j - s[i]] + f[i]); } else{ for(int j=0; j<=200000+s[i]; j++) dp[j] = max(dp[j], dp[j - s[i]] + f[i]); } } int ans = 0; for(int i=100000; i<=200000; i++){ if(dp[i] > 0) ans = max(dp[i] + i - 100000, ans); } printf("%d\n", ans); return 0;}
0 0
- poj 2184 Cow Exhibition
- POJ 2184 Cow Exhibition
- Poj 2184 Cow Exhibition
- poj 2184 Cow Exhibition
- poj 2184 Cow Exhibition
- POJ 2184 Cow Exhibition
- POJ-2184-Cow Exhibition
- POJ 2184 Cow Exhibition
- poj 2184 Cow Exhibition
- poj 2184 Cow Exhibition
- poj 2184 Cow Exhibition
- poj 2184--Cow Exhibition
- POJ 2184Cow Exhibition
- poj 2184 Cow Exhibition
- poj 2184:Cow Exhibition
- poj-2184-Cow Exhibition
- POJ 2184 Cow Exhibition
- Poj 2184 Cow Exhibition
- MFC中获取各种类(文档、视图、框架、应用程序)指针的方法
- [IOS开发] 高度自定义 UITabBarController, 支持StoryBoard
- POJ 1523 SPF Tarjan求割点
- 最短路--(迪杰斯特拉)
- 设计模式六大原则(6):开闭原则OCP(The Open/Closed Principle )
- poj 2184--Cow Exhibition
- DiskLruCache
- java.lang.OutOfMemoryError (OOM)解密 & Java heap dumps 解析 (一)
- C++学习——Overriding(1)
- IO流
- 。。。
- 数独
- 第一篇、Java入门
- OJ(Online Judge)系统及ACM测试题库大全