動態規劃解決這個問題
,具體內容我不多說,轉的內容是:
13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7
1.完全位於子數組A[low..mid]中, 因此low<=i<=j<=mid;
2.完全位於子數組A[mid + 1..high]中,因此mid<=i<=j<=high;
3.跨越了中點,因此low<=i<=mid<j<=high;
中或者跨越中點的所有子數組中和最大者。
代碼:
#include <iostream>const int Infinite = -10000;//int max_left = 0;//int max_right = 0;using namespace std;int FindMaxCrossSubarray(int A[], int low, int mid, int high) //跨越{ int left_sum = Infinite; int sum = 0; for (int i = mid; i >= low; i--) //左半部的最大子數組 { sum += A[i]; if (sum >left_sum) { left_sum = sum; //max_left = i; } } int right_sum = Infinite; sum = 0; for (int i = mid + 1; i <= high; i++) //右半部的最大子數組 { sum += A[i]; if (sum > right_sum) { right_sum = sum; //max_right = i; } } return left_sum + right_sum;}int FindMaxSubarray(int A[], int low, int high){ int left_sum, right_sum, cross_sum; if (high == low) //一個元素 { return A[low]; } else { int mid = (low + high) / 2; //分治 left_sum = FindMaxSubarray(A, low, mid); //前半部 right_sum = FindMaxSubarray(A, mid + 1, high); //後半部 cross_sum = FindMaxCrossSubarray(A, low, mid, high); //跨越前後 if (left_sum >= right_sum && left_sum >= cross_sum) //最大子數組在左邊 return left_sum; else if (right_sum >= left_sum && right_sum >= cross_sum) //右邊 return right_sum; else //跨越 return cross_sum; }}int main(){ int a[] = {13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7}; //int a[] = {23, -4}; int length = sizeof(a) / sizeof(int); cout<<FindMaxSubarray(a, 0, length - 1)<<endl; //cout<<"最大子序列的下標:"<<max_left<<"->"<<max_right; return 0;}
歡迎指點,o(∩_∩)o