将最大子数组分三种情况讨论,一定在left段,right段,已经过mid两侧
mid = (low+high)/2
- low«i«j«mid
- low«i«mid«high
- mid+1«i«j
#include <iostream> #include <cstdlib> #define inf 0x3f3f3f using namespace std; int findCrossingMaxSubarray(int a[],int low,int mid,int high,int &cros_left,int &cros_right){ int left_sum=-inf; int sum=0; //find the cros_left for(int i=mid;i>=low;i--){ sum += a[i]; if(left_sum<sum){ left_sum = sum; cros_left = i; } } sum = 0; int right_sum = -inf; //find the cros_right for(int i=mid+1;i<=high;i++){ sum += a[i]; if(right_sum<sum){ right_sum = sum; cros_right = i; } } return left_sum+right_sum; } int findMaxSubarray(int a[],int low,int high,int &left,int &right){ if(low==high){ left = low; right = high; return a[low]; } int mid = (low+high)/2; //find the left max subarray int left_left,left_right; int left_sum; left_sum = findMaxSubarray(a,low,mid,left_left,left_right); int right_left,right_right; int right_sum; right_sum = findMaxSubarray(a,mid+1,high,right_left,right_right); //find the crossing mx subarray int crossing_left,crossing_right; int crossing_sum; crossing_sum = findCrossingMaxSubarray(a,low,mid,high,crossing_left,crossing_right); //the first or the last if(left_sum>=right_sum&&left_sum>crossing_sum){ left = left_left; right = left_right; return left_sum; } else if(right_sum>=left_sum&&right_sum>crossing_sum){ left = right_left; right = right_right; return right_sum; } else{ left = crossing_left; right = crossing_right; return crossing_sum; } } int main() { int n; cin>>n; int *a = (int*)malloc(sizeof(int)*n); for(int i=0;i<n;i++) cin>>a[i]; int left,right,sum; sum = findMaxSubarray(a,0,n-1,left,right); cout<<"left:"<<left<<" "<<"right:"<<right<<" "<<"sum:"<<" "<<sum; free(a); //cout << "Hello world!" << endl; return 0; }
hd1003