POJ 2479 最大子段和 问题

POJ 2479 最大子段和 问题

  1  /* 最大子序和问题,从左到右和从右到左用了不同的方法
  2  求从右到左时我用了
  3      for(int i=0;i<n;++i)
  4      {
  5          if(b+p[i]>0)
  6          {
  7              b=b+p[i];
  8          }
  9          else
 10          {
 11              b=0;
 12          }
 13          if(b>max)max=b;
 14      }
 15      cout<<max<<endl;
 16  这个方法。而从右到左求时,用这方法时
 17  如下
 18          sum2[n-1]=0;
 19          for(int i=n-1;i>=1;--i)
 20         {
 21             if(sum2[i+1]+p[i]>0)
 22             {
 23                 sum2[i]=sum2[i+1]+p[i];
 24             }
 25             else
 26             {
 27                 sum2[i]=0;
 28             }
 29             if(sum2[i]>max)max=sum2[i];
 30             一直W。。TAT.不知为何.所以换了个方法如下。
 31  主要思路:两个不相交字串,一个从左到右求出sum1[i]为右边前i个数中最大字串(未必从第一个开始,也未必最后一个结束,的任意子串),
 32  而从这时的i到n中求出最大子串值和其相加时,未必为最大和。所以先保证从右到左为最大,求出i,再从i到1求出。
 33  再从和中挑出最大的,若两个都挑出最大的,用函数的话会超时很惨的。 */
 34 
 35  #include < iostream >
 36  #include < stdio.h >
 37  using   namespace  std;
 38  // =====================================================
 39  #define  M 50001
 40  int  k;
 41  int  p[M],sum1[M],sum2[M];
 42  // =====================================================
 43  int  main()
 44  {
 45       int  n;
 46       int  max =- M;
 47       //  freopen( "in.txt", "r", stdin);
 48       // freopen( "out.txt", "w+", stdout); 
 49     scanf( " %d " , & k);
 50      while (k -- )
 51     {
 52          int  n;
 53         scanf( " %d " , & n);
 54 
 55          int  max =- M;
 56          int  m =- M;
 57         scanf( " %d " , & p[ 0 ]);
 58       
 59        sum1[ 0 ] = p[ 0 ];
 60      
 61 
 62         for ( int  i = 1 ;i < n; ++ i)
 63        {
 64             scanf( " %d " , & p[i]);
 65              if (sum1[i - 1 ] + p[i] > 0 )
 66             {
 67                 sum1[i] = sum1[i - 1 ] + p[i];
 68             }
 69              else
 70             {
 71                 sum1[i] = 0 ;
 72             }
 73         }
 74         sum2[n - 1 ] = p[n - 1 ];
 75          for ( int  i = n - 1 ;i >= 1 ; -- i)
 76         {
 77              if (sum2[i] > 0 )
 78             {
 79                 sum2[i - 1 ] = sum2[i] + p[i - 1 ];
 80             }
 81              else
 82             {
 83                 sum2[i - 1 ] = p[i - 1 ];
 84             }
 85              if (sum2[i] > max)max = sum2[i];
 86 
 87              if (sum1[i - 1 ] + max > m)
 88             {
 89                 m = sum1[i - 1 ] + max;
 90             }
 91          }
 92          printf( " %d\n " ,m);
 93     }
 94  }
 95       
 96         
 97 
 98 
 99 
100 
101       
102         
103 
104 

你可能感兴趣的:(POJ 2479 最大子段和 问题)