Chinaunix首页 | 论坛 | 博客
  • 博客访问: 349221
  • 博文数量: 63
  • 博客积分: 1412
  • 博客等级: 中尉
  • 技术积分: 648
  • 用 户 组: 普通用户
  • 注册时间: 2011-03-10 23:07
文章分类

全部博文(63)

文章存档

2012年(42)

2011年(21)

我的朋友

分类: C/C++

2011-03-12 23:37:39

原题链接如下:
这道题,利用的方法是“求最大连续子段和”的方法。
核心思想是:
用数组A[N]记录所要求的数组,用数组B[N]来记录连续子段的和
可以知道:
初时值B[0] = A[0];
当B[K-1]>0时,,B[K]=B[K-1]+A[K]
当B[K-1]<0时,B[K]=A[K]

解题如下:
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>

  4. #define MAXNUM 50100

  5. long long    data[MAXNUM];
  6. long long    left[MAXNUM];
  7. long long    right[MAXNUM];

  8. int    main()
  9. {
  10.     int    N, n;
  11.     int    i, j;
  12.     long    long max, prevalue;

  13.     scanf( "%d", &N );  //N表示共有N组数组

  14.     for( i=0; i<N; i++ )
  15.     {
  16.         scanf( "%d", &n );  //n表示每组数据的个数
  17.         if( n > MAXNUM )
  18.         {
  19.             continue;
  20.         }
  21.     
  22.         scanf( "%lld", &data[1] );
  23.         left[1] = max = prevalue = data[1];

  24.         for( j=2; j<=n; j++ )
  25.         {
  26.             scanf( "%lld", &data[j] );
  27.             
  28.             //按照求最大连续子段和的方法,求最大连续子段的和
  29.             max_from_first_to_last( j, data[j], left, &prevalue, &max );
  30.         }
  31.         
  32.         op_data( n );
  33.     }    

  34.     return 0;
  35. }

  36. int    op_data( int n )
  37. {
  38.     long long    max = 0;
  39.     int        i;

  40.     max_from_last_to_first( n );
  41.     //print_array( n, left );
  42.     ////print_array( n, right );

  43.     getmax( n );

  44.     return 0;
  45. }

  46. int    print_array( int n, long long *a )
  47. {
  48.     int    i;
  49.     for( i=1; i<=n; i++ )
  50.     {
  51.         printf( "%lld ", a[i] );
  52.     }    
  53.     printf( "\n" );
  54. }

  55. /*
  56.     从数组的左往右求最大连续子段的和
  57.    
  58.     int:            i - array index
  59.     long long data        data[i]'s value    
  60.     long long *left:    it is a array
  61.     long long *prevalue:    sum of data, which is from 1 to i-1
  62.     long long *max    
  63. */

  64. int    max_from_first_to_last( int i, long long data, long long *left, long long *prevalue, long long *max )
  65. {
  66.     if( *prevalue > 0 )
  67.     {
  68.         *prevalue += data;
  69.     }
  70.     else
  71.     {
  72.         *prevalue = data;
  73.     }

  74.     if( *prevalue > *max )
  75.     {
  76.         *max = *prevalue;
  77.     }

  78.     left[i] = *max;

  79.     return 0;
  80. }
  81. /*
  82. 从数组的右往左求最大连续子段的和
  83. */
  1. int    max_from_last_to_first( int n )
  2. {
  3.     int    i = 0 ;
  4.     long long    max, value;

  5.     max = value = right[n] = data[n];

  6.     for( i=n-1; i>=1; i-- )
  7.     {
  8.         if( value > 0 )    
  9.         {
  10.             value += data[i];
  11.         }
  12.         else
  13.         {
  14.             value = data[i];
  15.         }

  16.         if( value > max )
  17.         {
  18.             max = value;
  19.         }

  20.         right[i] = max;
  21.     }    

  22.     return 0;
  23. }

  24. int    getmax( n )
  25. {
  26.     int i;
  27.     long long max, tmp;

  28.     max = left[1] + right[2];
  29.     for( i=2; i<n; i++ )
  30.     {
  31.         tmp = left[i]+right[i+1];    
  32.         if( tmp > max )
  33.         {
  34.             max = tmp;
  35.         }
  36.     }

  37.     printf( "%lld\n", max );
  38. }

阅读(1267) | 评论(0) | 转发(0) |
0

上一篇:内核中通知链的实现

下一篇:北大1050题

给主人留下些什么吧!~~