利用分治策略來解決最大子陣列問題
阿新 • • 發佈:2019-01-23
#include<iostream> #include<climits> using namespace std; //定義子陣列結構體,分別代表子陣列的下界和上界,以及和 struct sub_array { int max_left; int max_right; int max_sum; }; //尋找跨越中點的最大子陣列的函式 sub_array Find_Max_Crossing_Subarray(int *A, int low, int mid, int high) { int left_sum = INT_MIN; int right_sum = INT_MIN; int sum = 0; sub_array cross_array; //計算中點左側的最大子陣列 for (int i = mid; i >= 1; i--) { sum = sum + A[i]; if (sum > left_sum) { left_sum = sum; cross_array.max_left = i; } } sum = 0; //計算中點右側的最大子陣列 for (int j = mid + 1; j <= high; j++) { sum = sum + A[j]; if (sum > right_sum) { right_sum = sum; cross_array.max_right = j; } } //將二者進行合併 cross_array.max_sum = left_sum + right_sum; return cross_array; } //尋找最大子陣列的函式 sub_array Find_Maximun_Subarray(int *A, int low, int high) { int mid; if (high == low) { //陣列中只有一個元素的情況 sub_array temp; temp.max_left = low; temp.max_right = high; temp.max_sum = A[low]; return temp; } else { mid = (low + high) / 2; sub_array cross_array; sub_array left_array; sub_array right_array; left_array = Find_Maximun_Subarray(A, low, mid); //計算左子陣列 right_array = Find_Maximun_Subarray(A, mid + 1, high); //計算右子陣列 cross_array = Find_Max_Crossing_Subarray(A, low, mid, high); //計算橫跨中點的子陣列 //尋找最大的情況 if (left_array.max_sum >= right_array.max_sum && left_array.max_sum >= cross_array.max_sum) { return left_array; } else if (right_array.max_sum >= left_array.max_sum && right_array.max_sum >= cross_array.max_sum) { return right_array; } else { return cross_array; } } } int main() { int num; cin >> num; int *B = new int[num]; int *A = new int[num]; for (int i = 0; i < num; i++) { cin >> B[i]; } for (int i = 1; i < num; i++) { A[i] = B[i] - B[i-1]; } sub_array solution; solution = Find_Maximun_Subarray(A, 1, num-1); cout << solution.max_left<<" "<< solution.max_right<<" "<<solution.max_sum << endl; system("pause"); }