Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1829141
  • 博文数量: 195
  • 博客积分: 4227
  • 博客等级: 上校
  • 技术积分: 2835
  • 用 户 组: 普通用户
  • 注册时间: 2010-09-04 10:39
文章分类

全部博文(195)

文章存档

2013年(1)

2012年(26)

2011年(168)

分类: LINUX

2011-06-10 11:12:09

最大子序列和问题:给定整数A1, A2, ..., An(可能有负数),ΣAk的最大值(为方便起见,如果所有整数均为负数,则最大子序列和为0)。

      例:输入-2,11,-4,13,-5,-2时,答案为20(从A2到A4)。

 

算法1:穷举所有可能,立方运行时间。

 1 int MaxSubsequenceSum( const int A[ ], int N )
 2 {
 3     int ThisSum, MaxSum, i, j, k;
 4 
 5     MaxSum = 0;
 6     for( i = 0; i < N; i++ )
 7         for( j = i; j < N; j++ )
 8         {
 9             ThisSum = 0;
10             for( k = i; k <= j; k++ )
11                 ThisSum += A[ k ];
12 
13             if( ThisSum > MaxSum )
14                 MaxSum = ThisSum;
15         }
16         return MaxSum;
17 }


算法2: 平方运行时间。

 1 int MaxSubsequenceSum( const int A[ ], int N )
 2 {
 3     int ThisSum, MaxSum, i, j;
 4 
 5     MaxSum = 0;
 6     for( i = 0; i < N; i++ )
 7     {
 8         ThisSum = 0;
 9         for( j = i; j < N; j++ )
10         {
11             ThisSum += A[ j ];
12 
13             if( ThisSum > MaxSum )
14                 MaxSum = ThisSum;
15         }
16     }
17     return MaxSum;
18 }


算法3:分治策略,NlogN运行时间。

 1 static int Max3( int A, int B, int C )
 2 {
 3     return A > B ? A > C ? A : C : B > C ? B : C;
 4 }
 5 
 6 static int MaxSubSum( const int A[ ], int Left, int Right )
 7 {
 8     int MaxLeftSum, MaxRightSum;
 9     int MaxLeftBorderSum, MaxRightBorderSum;
10     int LeftBorderSum, RightBorderSum;
11     int Center, i;
12 
13     if( Left == Right ) /* Base case */
14         if( A[ Left ] > 0 )
15             return A[ Left ];
16         else
17             return 0;
18 
19     Center = ( Left + Right ) / 2;
20     MaxLeftSum = MaxSubSum( A, Left, Center );
21     MaxRightSum = MaxSubSum( A, Center + 1, Right );
22 
23     MaxLeftBorderSum = 0; LeftBorderSum = 0;
24     for( i = Center; i >= Left; i-- )
25     {
26         LeftBorderSum += A[ i ];
27         if( LeftBorderSum > MaxLeftBorderSum )
28             MaxLeftBorderSum = LeftBorderSum;
29     }
30 
31     MaxRightBorderSum = 0; RightBorderSum = 0;
32     for( i = Center + 1; i <= Right; i++ )
33     {
34         RightBorderSum += A[ i ];
35         if( RightBorderSum > MaxRightBorderSum )
36             MaxRightBorderSum = RightBorderSum;
37     }
38 
39     return Max3( MaxLeftSum, MaxRightSum,
40         MaxLeftBorderSum + MaxRightBorderSum );
41 }
42 
43 int MaxSubsequenceSum( const int A[ ], int N )
44 {
45     return MaxSubSum( A, 0, N - 1 );
46 }


算法4:线性运行时间。

 1 int MaxSubsequenceSum( const int A[ ], int N )
 2 {
 3     int ThisSum, MaxSum, j;
 4 
 5     ThisSum = MaxSum = 0;
 6     for( j = 0; j < N; j++ )
 7     {
 8         ThisSum += A[ j ];
 9 
10         if( ThisSum > MaxSum )
11             MaxSum = ThisSum;
12         else if( ThisSum < 0 )
13             ThisSum = 0;
14     }
15     return MaxSum;
16 }


算法5:修改算法4增加最大子序列和的子序列起始位置和终止位置。

 1 int MaxSubsequenceSum( const int A[], int N, int& x, int& y )
 2 {
 3     int ThisSum, MaxSum, t, j;
 4 
 5     t = 0;
 6     ThisSum = MaxSum = 0;
 7     for( j = 0; j < N; j++ )
 8     {
 9         ThisSum += A[j];
10         if( ThisSum > MaxSum )
11         {
12             MaxSum = ThisSum;
13             y = j;
14         }else if( ThisSum < 0 )
15         {
16             ThisSum = 0;
17             t = j + 1;
18         }
19         if ( t <= y )
20             x = t;
21     }
22     return MaxSum;
23 }
24 
25 int main()
26 {
27     int x = 0, y = 0;
28     int A[] = {4-35-2-126-12};
29 
30     int r = MaxSubsequenceSum(A, sizeof(A)/sizeof(A[0]), x, y);
31     printf("%d, %d, %d\n", r, x+1, y+1);
32 
33     return 0;
34 }
轉自:http://www.cnblogs.com/shengjin/archive/2010/01/08/1641975.html
阅读(1202) | 评论(0) | 转发(0) |
0

上一篇:C /C++时间函数

下一篇:Linux下Fork与Exec使用

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