/*DJ.W 2012.12.27代碼功能: 輸入: 一個整型數組輸出: 該數組能得到的最大連續元素和如對輸入 1 -2 -4 7 -6 9 最大連續元素和為10 (7 + (-6) + 9) 問題以及演算法思想來自《編程珠璣(第二版)》P77 */#include <iostream>using namespace std;#define max(a, b) (a>b? a:b)/*二分思想思路,將數組從中間分為三個部分,左半部分,右半部分,和交界部分數組中最大連續元素和必定是三者其一,也就是最大的那一個。對於左右半部分,可以直接遞迴,中間部分就直接從中間開始向兩邊擴散。複雜度為O(n) 整個演算法複雜度為O(nlgn)這個解法需要認真想想它是怎樣保證得到的和一定是連續元素塊的。*/int maxsum(int* p, int start, int end){//終止條件 遞迴到長度為1的子數組,這個時候//自然是該數是正就加上是負則捨去(返回0)if(start == end){if(p[start] > 0)return p[start];elsereturn 0;}//找到中點int mid = (start+end)/2;//從中點向左擴充 找到向左能得到的最大和int sum_mid = 0;int temp = 0;for (int i= mid; i>=start; i--){temp = temp+p[i];if (temp > sum_mid)sum_mid = temp;}temp = sum_mid;//從中點向右擴充 找到向右擴充能得到的最大和for (i = mid+1; i<=end; i++){temp = temp+p[i];if (temp > sum_mid)sum_mid = temp;}//遞迴左右兩半部分 得到三個部分中最大和return max(max(maxsum(p, start, mid), maxsum(p, mid+1, end)), sum_mid);}/*掃描法演算法思想:從左至右掃描數組A,當掃描到i時,設立兩個變數sumCur和maxSofarsumCur為當前掃描到的下標i之前得到的累加值。maxSofar是當前得到過的最大元素和。如果sumCur = sum(A[0]...A[i])<=0那麼可以判定A[0...i]必定不會在最終得到的最大連續元素和的序列中(這裡假設我們力求得到的連續元素個數最少,因此加上了=)。因此我們重設sumCur=0(相當於捨棄了A[0...i])如果sumCur > 0 則繼續掃描A[i+1] 此時如果A[i+1]>=0 那麼maxSofar = sumCur+A[i+1] 否則maxSofar不變。當掃描完數組後maxSofar即為所求*/int maxsum_scan(int* arr, int size){int sumCur = 0;int maxSofar = 0;for (int i=0; i<size; i++){sumCur = max(sumCur+arr[i], 0);maxSofar = max(maxSofar, sumCur);}return maxSofar;}int main(){int test[10] = {10, -9, 6, 33, -12, 5, 19, 8, 13, -2};//int sum = maxsum(test, 0, 9);int sum = maxsum_scan(test, 9);cout<<"Test Sum = "<<sum<<endl;return 0;}