PKU 2184 Cow Exhibition 动态规划01背包

http://poj.org/problem?id=2184

题意:

  第一行为N,代表下面有N组数据,下面每一行有S和F分别代表一头牛的智商和幽默度(有正有负),现在要你算出

要选哪些牛,是求当智商大于0时,幽默度最大的时候的智商与幽默度的总和,总和如果为负的话输出0,正的话直接输

出总和的值。

 

坑爹:

  因为这相当于01背包的问题了,智商为背包中的体积,幽默度为背包中的价值,但是智商可能为负,访问数组下标

的时候会错误。

  初始化要将 数组 f 赋值为 -0x3fffffff(其实-200000就够了)    并把f[1000000] = 0  因为幽默度能可能出现

负数。

 

解法:

  要解决数组下标可能会访问到负的时候的问题,我将整个数组下标+100000 然后在后面计算总和的时候减去100000

就行了,智商的范围为什么是-100000到100000? 因为有100组数据,如果每个都是1000的话就是100000了。

  进行01背包的时候害要分cost是正是负,当正的时候 j - 200000 → cost  , 当负的时候 j - cost → 200000 ,

因为0到100000的时候智商是为负的,100000到200000的时候智商是为正的。

 

View Code
  1 #include<iostream>
  2 using namespace std;
  3 
  4 const int maxn = 200000 + 1001;
  5 const int INF = -1 * 0x3fffffff;
  6 int N;
  7 
  8 struct Cow
  9 {
 10     int TS;
 11     int TF;
 12 };
 13 
 14 struct Cow cow[maxn];
 15 int f[maxn];
 16 
 17 int max(int a,int b)
 18 {
 19     return a > b ? a : b;
 20 }
 21 
 22 void init()
 23 {
 24     int i;
 25     for(i=0; i<maxn; i++)
 26     {
 27         f[i] = INF;
 28     }
 29     f[100000] = 0;
 30 }
 31 
 32 void ZeroOnePack(int cost,int weight)            //逆向
 33 {
 34     int j;
 35     for(j=200000; j>=cost; j--)
 36     {
 37         if(f[j-cost] > INF)
 38         {
 39             f[j] = max(f[j] , f[j-cost] + weight);
 40         }
 41     }
 42 }
 43 
 44 void ZeroOnePack1(int cost,int weight)           //正向
 45 {
 46     int j;
 47     for(j=cost; j<=200000+cost; j++)
 48     {
 49         if(f[j-cost] > INF)
 50         {
 51             f[j] = max(f[j] , f[j-cost] + weight);
 52         }
 53     }
 54 }
 55 
 56 int main()
 57 {
 58     while(cin>>N)
 59     {
 60         int i;
 61         memset(f,0,sizeof(f));
 62         init();
 63 
 64         for(i=1; i<=N; i++)
 65         {
 66             cin>>cow[i].TS>>cow[i].TF;
 67         }
 68 
 69         for(i=1; i<=N; i++)
 70         {
 71             if(cow[i].TS < 0 && cow[i].TF < 0)
 72             {
 73                 continue;
 74             }
 75             if(cow[i].TS > 0)
 76             {
 77                 ZeroOnePack(cow[i].TS,cow[i].TF);
 78             }
 79             if(cow[i].TS <= 0)
 80             {
 81                 ZeroOnePack1(cow[i].TS,cow[i].TF);
 82             }
 83         }
 84         
 85         int MAX = INF;
 86         for(i=100000; i<=200000; i++)
 87         {
 88             if(f[i] >= 0)
 89             {
 90                 MAX = max(MAX , f[i] + i - 100000);
 91             }
 92         }
 93         if(MAX < 0)
 94         {
 95             cout<<0<<endl;
 96         }
 97         else
 98         {
 99             cout<<MAX<<endl;
100         }
101     }
102     return 0;
103 }

 

 

 

 

转载于:https://www.cnblogs.com/pcpcpc/archive/2012/09/10/2679043.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值