Cow Exhibition 解题报告

总时间限制:  1000ms  内存限制:  65536kB

描述

"Fat and docile, big and dumb, they look so stupid, they aren't much 
fun..."
- Cows with Guns by Dana Lyons

The cows want to prove to the public that they are both smart and fun. In order to do this, Bessie has organized an exhibition that will be put on by the cows. She has given each of the N (1 <= N <= 100) cows a thorough interview and determined two values for each cow: the smartness Si (-1000 <= Si <= 1000) of the cow and the funness Fi (-1000 <= Fi <= 1000) of the cow.

Bessie must choose which cows she wants to bring to her exhibition. She believes that the total smartness TS of the group is the sum of the Si's and, likewise, the total funness TF of the group is the sum of the Fi's. Bessie wants to maximize the sum of TS and TF, but she also wants both of these values to be non-negative (since she must also show that the cows are well-rounded; a negative TS or TF would ruin this). Help Bessie maximize the sum of TS and TF without letting either of these values become negative.

输入

* Line 1: A single integer N, the number of cows

* Lines 2..N+1: Two space-separated integers Si and Fi, respectively the smartness and funness for each cow.

输出

* Line 1: One integer: the optimal sum of TS and TF such that both TS and TF are non-negative. If no subset of the cows has non-negative TS and non- negative TF, print 0.

样例输入

5

-5 7

8 -6

6 -3

2 1

-8 -5

样例输出

8

提示

OUTPUT DETAILS:

Bessie chooses cows 1, 3, and 4, giving values of TS = -5+6+2 = 3 and TF 
= 7-3+1 = 5, so 3+5 = 8. Note that adding cow 2 would improve the value 
of TS+TF to 10, but the new value of TF would be negative, so it is not 
allowed.

来源

USACO 2003 Fall

1题目分析

直接分析不废话,N个数据,每次输入Si,fi,求当si以及fi的各自的和Ts和Tf均大于0时的Ts+Tf的最大值.

  坦白说,一开始以为是动态规划的的问题,可是后来想想,可能会缺少一些中间情况。于是又想到了01背包,可是后来发现不是超时就是超内存,于是去参观下大神们的代码。最后终于懂了!!

2解决方案

 根据题目要求,因为中间存在负值的情况,所以不能够直接套用01背包的模板,同时我们需要考虑到数据属于100组,每组数据都在-1000-1000,所以我们不能够用二维数组来存储,需要用传说中的滚动数组。

3 具体实施

(1)       定义一个dp数组,用来存储过程中的中间数据,其中dp[i]中的i代表着si+100000,dp[i]则代表此时的最大的fi

(2)       每次提升i的值,更新fi

(3)       考虑到si的正负性会影响到过程中的i-s[i]的值

当si>0   i-si<i

  Si<0   i-si>i

因为是滚动数组,每次选取的则是dp[i]=max(dp[i],dp[i-si]+fi),所以考虑到上面的情况,当si>0的时候,我们从0-200000开始装背包,同理si<0的时候则是反向装背包,由于dp[i]中可以存在负值,所以我们初始化的时候定义一个负无穷 建议采用(0x3fffffff)然后加负数.

4 具体代码

 

#include<iostream>

#include<cstdio>

#include<cstring>

using namespace std;

#define INF 0x3fffffff

int Max(int a,int b)

{

         return a>b?a:b;

}

int main()

{

         //freopen("in.txt","r",stdin);

         int dp[200010];

         int s,f,n;

         int i,j;

         for(i=0;i<=200000;i++)

                   dp[i]=-INF;

         dp[100000]=0;  //初始化

         scanf("%d",&n);

         for(i=0;i<n;i++)

         {

                   scanf("%d%d",&s,&f);

                   if(s<0 && f<0)

                            continue;

                   if(s>0)

                   {

                            for(j=200000;j>=s;j--)

                            {

                                     dp[j]=Max(dp[j],dp[j-s]+f);   //更新

                            }

                   }

                   else

                   {

               for(j=0;j<=200000+s;j++)

                            {

                                     dp[j]=Max(dp[j],dp[j-s]+f); //更新

                            }

                   }

         }

         int mmax=-INF;

         for(i=100000;i<=200000;i++)

         {

       if(dp[i]>=0)

            {

                      mmax=Max(mmax,dp[i]+i-100000);

            }

         }

         printf("%d\n",mmax);

         return 0;

}

时间

预计时间: 60minutes  实际时间:240minutes

时间差原因分析:

(1)     对01 背包的滚动数组的用法理解不清楚

(2)     对01背包问题分析不够透彻,不能够灵活运用

第二次分析完全后,代码书写时间为10分钟。一次A掉该题目

 

收获:

(1)     如果将问题化为对一堆一组一组的数据的求其中在限制情况下的最优解问题。

(2)     对滚动数组的最初位置赋初始值,需要记得

最后,这个题目的想法确实很好,我觉得甚至可以当做典型的01背包问题了。

发布了16 篇原创文章 · 获赞 2 · 访问量 8892

猜你喜欢

转载自blog.csdn.net/hihei_set/article/details/47378763