POJ 2184 Cow Exhibition(01背包变形)
2015-08-29 14:24
246 查看
题意: 给你N头奶牛,每头奶牛都有两种属性S和F、,每种属性的属性值可以为负值、问你S的和和F的和的最大值为多少、
思路: 背包转换,可以S的值看做容量F的值看做价值、 依照正常的背包做就可以了、最后只要遍历一遍所有和值找出最大值输出便可、 有一个问题需要注意,那就是有负值的问题 因为有负值,我们可以将他在数组里面的位置移位,移到为整数的位置、 也就是每个S值最小为-1000 最多有100个,也就是说将0~100000看做左边的值、 100000~200000看做正数值、 要注意的是将dp[100000]的值赋值为0,其余位置负值为负数的极小值、因为我要求的值是固定值,在最后我需要将这个i值与我的dp[i[值进行求和、输出、
所以,每个值里面代表的是,恰好将某个容量的背包装满的情况下我才可以将之加入、否则会影响我的求值、 还需要注意的是,如果S[i]的值>0那么我们正常的按照求dp值来求取我需要的数值、 那么如果S[i]<0的话就要将之从小到大来选择、 因为此时我的S[i]值为负数,那么 j- S[i] >j 按照我们正常的dp[的思想从后向前求的话,会影响后面的值,所以要从前向后选取、那么是从0一直到哪个位置呢? 一定是200000+S[i] 因为S[i]<0 所以我最大的值是不可能超过200000+S[i]的、 还有就是要注意的是,S[i]
<0&&F[i]<0的情况、 因为S[i]<0的时候,我的存取情况是按照从0一直到200000+S[i] 来选择的、 那么既然F[i]]<0的话、有可能会发生数组越界的情况、 需要加个判断来解决这个问题、 最后追寻有将之便利一遍找出最大的和值将之输出便可、
哦对了,还有一些需要注意的问题,那就是首先S[i]>0的时候,为什么我要将之由200000~S[i] 因为我要求解的是每一个能装载S[i]的不同容量的背包的值,因为我要求出最大值嘛、有可能虽然有的S[i]的值并不是很大,但是F[i] 的值是会影响我最后求值的、 所以我每一种情况都不要放弃,都要求出来、 而当S[i]<0的时候,我的S值的和值最大为200000+S[i] 跟刚才说的一样,每一种情况我都不放弃,因为我要求的是最后的S和F 的和值的最大值,并不是某种值的最大值、
我的代码不知为什么在POJ上面提交的时候用G++过得了,用C++就过不到,我也不知道为什么、 自己的知识量还是不够,还需努力学习~
AC代码:
思路: 背包转换,可以S的值看做容量F的值看做价值、 依照正常的背包做就可以了、最后只要遍历一遍所有和值找出最大值输出便可、 有一个问题需要注意,那就是有负值的问题 因为有负值,我们可以将他在数组里面的位置移位,移到为整数的位置、 也就是每个S值最小为-1000 最多有100个,也就是说将0~100000看做左边的值、 100000~200000看做正数值、 要注意的是将dp[100000]的值赋值为0,其余位置负值为负数的极小值、因为我要求的值是固定值,在最后我需要将这个i值与我的dp[i[值进行求和、输出、
所以,每个值里面代表的是,恰好将某个容量的背包装满的情况下我才可以将之加入、否则会影响我的求值、 还需要注意的是,如果S[i]的值>0那么我们正常的按照求dp值来求取我需要的数值、 那么如果S[i]<0的话就要将之从小到大来选择、 因为此时我的S[i]值为负数,那么 j- S[i] >j 按照我们正常的dp[的思想从后向前求的话,会影响后面的值,所以要从前向后选取、那么是从0一直到哪个位置呢? 一定是200000+S[i] 因为S[i]<0 所以我最大的值是不可能超过200000+S[i]的、 还有就是要注意的是,S[i]
<0&&F[i]<0的情况、 因为S[i]<0的时候,我的存取情况是按照从0一直到200000+S[i] 来选择的、 那么既然F[i]]<0的话、有可能会发生数组越界的情况、 需要加个判断来解决这个问题、 最后追寻有将之便利一遍找出最大的和值将之输出便可、
哦对了,还有一些需要注意的问题,那就是首先S[i]>0的时候,为什么我要将之由200000~S[i] 因为我要求解的是每一个能装载S[i]的不同容量的背包的值,因为我要求出最大值嘛、有可能虽然有的S[i]的值并不是很大,但是F[i] 的值是会影响我最后求值的、 所以我每一种情况都不要放弃,都要求出来、 而当S[i]<0的时候,我的S值的和值最大为200000+S[i] 跟刚才说的一样,每一种情况我都不放弃,因为我要求的是最后的S和F 的和值的最大值,并不是某种值的最大值、
我的代码不知为什么在POJ上面提交的时候用G++过得了,用C++就过不到,我也不知道为什么、 自己的知识量还是不够,还需努力学习~
AC代码:
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int inf=99999999; const int maxn=200010; const int maxm=110; int N; int S[maxm],F[maxm]; int dp[maxn]; int main() { while(scanf("%d",&N)!=EOF){ for(int i=0;i<=maxn;i++) dp[i]=-inf; for(int i=0;i<N;i++) scanf("%d %d",&S[i],&F[i]); dp[100000]=0; for(int i=0;i<N;i++){ if(S[i]<0&&F[i]<0) continue; if(S[i]>0){ for(int j=maxn;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=-inf; for(int i=100000;i<=200000;i++){ if(dp[i]>=0&&(i-100000+dp[i])>ans){ ans=i-100000+dp[i]; } } if(ans<0) printf("0\n"); else printf("%d\n",ans); } return 0; }
相关文章推荐
- Android Studio基本配置
- shell programing
- http 原生post 请求
- 数据结构基础笔记(一)【严蔚敏】
- Hadoop分布式文件系统
- C#中sealed关键字
- UVA - 201 Squares(模拟 + 暴力)
- myeclipse 安装反编译插件
- js性能优化-事件委托
- 在 Activity 之间传递参数————传递值对象
- 类和对象
- Android调用微信登陆、分享、支付
- Android调用微信登陆、分享、支付
- C#的类型、变量和值
- 类加载器
- Codeforces Round #251 (Div. 2) 439D Devu and his Brother(脑洞)
- WebService注解汇总
- 使用shell操作数据库
- 全局大喇叭 广播机制 Receiver
- Linux命令之文本搜索工具grep、egrep、fgrep