分治法写最大子列和问题

来源:互联网 发布:有房卡麻将源码自己做 编辑:程序博客网 时间:2024/05/29 12:48
    1. int Max3( int A, int B, int C )
    2. /* 返回3个整数中的最大值 */
    3.     return A > B ? A > C ? A : C : B > C ? B : C;
    4. }
    5.  
    6. int DivideAndConquer( int List[], int left, int right )
    7. /* 分治法求List[left]到List[right]的最大子列和 */
    8.     int MaxLeftSum, MaxRightSum; /* 存放左右子问题的解 */
    9.     int MaxLeftBorderSum, MaxRightBorderSum; /*存放跨分界线的结果*/
    10.  
    11.     int LeftBorderSum, RightBorderSum;
    12.     int center, i;
    13.  
    14.     if( left == right )  { /* 递归的终止条件,子列只有1个数字 */
    15.         if( List[left] > 0 )  return List[left];
    16.         else return 0;
    17.     }
    18.  
    19.     /* 下面是"分"的过程 */
    20.     center = ( left + right ) / 2; /* 找到中分点 */
    21.     /* 递归求得两边子列的最大和 */
    22.     MaxLeftSum = DivideAndConquer( List, left, center );
    23.     MaxRightSum = DivideAndConquer( List, center+1, right );
    24.  
    25.     /* 下面求跨分界线的最大子列和 */
    26.     MaxLeftBorderSum = 0; LeftBorderSum = 0;
    27.     for( i=center; i>=left; i-- ) { /* 从中线向左扫描 */
    28.         LeftBorderSum += List[i];
    29.         if( LeftBorderSum > MaxLeftBorderSum )
    30.             MaxLeftBorderSum = LeftBorderSum;
    31.     /* 左边扫描结束 */
    32.  
    33.     MaxRightBorderSum = 0; RightBorderSum = 0;
    34.     for( i=center+1; i<=right; i++ ) { /* 从中线向右扫描 */
    35.         RightBorderSum += List[i];
    36.         if( RightBorderSum > MaxRightBorderSum )
    37.             MaxRightBorderSum = RightBorderSum;
    38.     /* 右边扫描结束 */
    39.  
    40.     /* 下面返回"治"的结果 */
    41.     return Max3( MaxLeftSum, MaxRightSum, MaxLeftBorderSum + MaxRightBorderSum );
    42. }
    43.  
    44. int MaxSubseqSum3( int List[], int N )
    45. /* 保持与前2种算法相同的函数接口 */
    46.     return DivideAndConquer( List, 0, N-1 );
    47. }

0 0
原创粉丝点击