POJ 2184 Cow Exhibition 01背包
2016-07-27 19:20
239 查看
题目链接
题目大意就是给每个牛的Si和Fi,要你选出一些牛使他们的Si和Fi的总和最大,并且他们的Si的总和不为0,Fi也是一样。
一开始看确实不好想,后来看了别人才知道,把Si看成花费,Fi看成价值。
不就是我们熟悉的01背包了吗。
但是,问题来了,题目里有负数,所以这题难点就在这里,你需要想一个办法解决。
看看数据范围。发现最大-10w,最大+10w
扩大数组,设置基准为10w , 这样子 0 就代表-10w ,20w就代表10w
设置dp[100000] = 100000;
这样子就可以通过dp[x] 是否等于0来判断是否合法
但是如果Fi是负数,就得从小开始搜。
而且20w的数据范围,容易超时,所以一开始用l和r来识别所要用到的区间
下面贴代码
题目大意就是给每个牛的Si和Fi,要你选出一些牛使他们的Si和Fi的总和最大,并且他们的Si的总和不为0,Fi也是一样。
一开始看确实不好想,后来看了别人才知道,把Si看成花费,Fi看成价值。
不就是我们熟悉的01背包了吗。
但是,问题来了,题目里有负数,所以这题难点就在这里,你需要想一个办法解决。
看看数据范围。发现最大-10w,最大+10w
扩大数组,设置基准为10w , 这样子 0 就代表-10w ,20w就代表10w
设置dp[100000] = 100000;
这样子就可以通过dp[x] 是否等于0来判断是否合法
但是如果Fi是负数,就得从小开始搜。
而且20w的数据范围,容易超时,所以一开始用l和r来识别所要用到的区间
下面贴代码
#include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <queue> using namespace std; int dp[200005]; int mid = 100002; int n; int main() { dp[mid] = mid; int c,w; scanf("%d",&n); int l = mid,r = mid; for(int i=0;i<n;i++){ scanf("%d%d",&c,&w); l = min(l,l+c); r = max(r,r+c); if(c>0){ for(int j=r;j>=l;j--){ if(dp[j-c]) dp[j] = max(dp[j],dp[j-c]+w); } }else { for(int j=l;j<=r;j++){ if(dp[j-c]) dp[j] = max(dp[j],dp[j-c]+w); } } } int res = 0; for(int i=mid;i<=200005;i++){ if(dp[i]>=mid) res = max(res,dp[i]+i-mid-mid); } printf("%d\n",res); return 0; }
相关文章推荐
- 详解Android应用中屏幕尺寸的获取及dp和px值的转换
- 基于Android中dp和px之间进行转换的实现代码
- Android中dip、dp、sp、pt和px的区别详解
- 简单的四则运算
- 数的奇偶性
- ACMer博客瀑布流分析
- LFC1.0.0 版本发布
- ACM程序设计大赛题目分类
- 2015年acm国内排名
- Android dpi,dip,dp的概念以及屏幕适配
- 计算字符串最后一个单词长度
- Android px、dp、sp之间相互转换
- ACM网址
- 1272 小希的迷宫
- 1272 小希的迷宫
- hdu 1250 大数相加并用数组储存
- HP data protector软件学习1--基本角色与基本工作流程
- HP data protector软件学习2--软件组成与界面介绍
- 矩阵的乘法操作
- android中像素单位dp、px、pt、sp的比较