POJ 2184Cow Exhibition(01背包变形)

来源:互联网 发布:java gbk utf8 转换 编辑:程序博客网 时间:2024/05/21 16:47

题意: 给你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代码:

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


0 0
原创粉丝点击