標籤:lag 不同 font size 最大連續子數組 strong 時間演算法 問題 博文
線上性時間內非遞迴的求數組的最大連續子數組(連續和最大的子數組)。
題目給出思路為數組A[1...j+1]的最大和子數組,有兩種情況:a) A[1...j]的最大和子數組; b) 某個A[i...j+1]的最大和子數組,但思考很久沒有理解如何用這個思路設計線性時間演算法,希望有人能給予指點。
(i點是使A[1]+..+A[i]為負的一個值?)
目前的思路是,最大子數組一定位於從某個正數開始,全部求和<=0的一段數組中
從其實點i到目標點j,從第一個正數開始截取盡量長的一段數組,從第一個正數起的最大子數組即為當前數組的最大子數組,若數組和為負,則不可能作為更長數組最大子數組的組成部分(因為還不如從零直接取第一個正數),因此清零數組和並從接下來的第一個正數重新截取。
1 #include<iostream> 2 using namespace std; 3 4 int A[100]; 5 int main(){ 6 int size; 7 cin>>size; 8 bool neg_flag=true;//當全為負數時返回最大值。 9 int neg_max=-1e10;10 for(int i=0;i<size;i++){//輸入並判斷是否全為負。11 cin>>A[i];12 if(A[i]>=0){13 neg_flag=false;14 }15 if(A[i]>neg_max){16 neg_max=A[i];17 }18 }19 if(neg_flag==true){20 cout<<"max is "<<neg_max<<" start from "<<neg_max<<" to "<<neg_max<<endl;21 return 0;22 }23 int max=-1e10;//最大和。24 int s=-1;//最大子數組起點。25 int e=-1;//最大子數組終點。26 int add=0;//掃描子數組和。27 int i=0;//掃描子數組起點。28 int j=0;//掃描子數組終點。29 while(j<size){30 add+=A[j];31 if(add>=0){32 if(add>=max){33 max=add;34 s=i;35 e=j;36 }37 ++j;38 }39 else{40 ++j;41 i=j;42 if(j<size){43 add=0;44 }45 }46 }47 cout<<"max is "<<max<<" start from "<<A[s]<<" to "<<A[e]<<endl;48 49 }
http://www.cnblogs.com/bakari/p/4809684.html?ptvd
根據bakari的博文,還有動態規劃的方法,這裡的思路似乎可以用來解釋上面的代碼,但是還是不太能理解動態規劃法和區間法的區別到底是什麼
sum[i+1] = Max(sum[i] + A[i+1], A[i+1])
化簡之後,其實就是比較sum[i] ?> 0(sum[i] + A[i+1] ?> A[i+1])
1 /************************************************************************/ 2 /* 動態規劃(對應著上面的貪進法看,略有不同) 3 求A[1...j+1]的最大和子數組,有兩種情況: 4 1)A[1...j]+A[j+1]的最大和子數組 5 2)A[j+1] 6 dp遞推式: 7 sum[j+1] = max(sum[j] + A[j+1], A[j+1]) 8 /************************************************************************/ 9 int MaxSubArraySum_dp(int arr[], int len)10 {11 if (len <= 0)12 exit(-1);13 int nMax = INT_MIN;14 int sum = 0;15 16 for (int i = 0; i < len; i ++) {17 if (sum >= 0) 18 sum += arr[i];19 else20 sum = arr[i];21 if (sum > nMax)22 nMax = sum;23 }24 return nMax;25 }
[演算法導論]4.1-5最大連續子數組問題