NOIP 最大欄位和問題 難點分析和C 實現

2022-06-28 02:30:16 字數 1506 閱讀 9584

給定n個數組成的序列,求其中最大子段和,並規定其中如果所有數均為負值的時候,那麼最大欄位和為零。

解決這樣的問題需要用的演算法是:分治法

1. 劃分兩個長度基本相同的子段,得出以下三種情況

2. 如果最大和出現在左邊,就左邊最大子段和為解

3. 如果最大和出現在右邊,就右邊最大子段和為解

4. 如果是最大和在左子段的最右邊的數組成,和右子段的最左邊的數組成,那麼就合併這兩個子段和,得到最終的解

1. 遞迴法,要熟悉遞迴機制,那麼就比較好理解了

2. 如何把三種情況都很好的計算出來並且合併起來。這也是分治法思想的精要。

[cpp]

#include

#include

using namespace std;  

template

t sectionmaxsum(vector& vt, int lindex, int rindex)

//index range [1,n] <=> c++index range [0, n-1]  

t sum  = t(0);  

//情況0:如果只有乙個元素; 也就是遞迴的結束條件,這也是遞迴演算法的必要條件  

//這個演算法的話必然會分治到這個情況,然後再逐層退出返回遞迴求的結果  

if(lindex == rindex)  

if(vt[lindex-1]>0)   sum = vt[lindex-1];  

else                sum = 0;  

else  

//分治,劃分兩個相同長度的兩個子串行  

int midindex = (lindex+rindex)/2;  

//情況1:最大子段和為左邊序列的最大子段,遞迴求解,注意下標設計  

t lsum = sectionmaxsum(vt, lindex, midindex);  

//情況2:最大子段和為右邊序列的最大子段,遞迴求解,  

//注意:midindex不加1的話,就會出現遞迴棧溢位  

t rsum = sectionmaxsum(vt, midindex+1, rindex);  

//情況3:最大子段為兩個左右子段的最大子段的和  

t lsubmaxsum = t(0);  

t ltempsum = t(0);  

for(int i = midindex-1; i>=lindex-1; i--)

//注意:這裡lindex-1,如果是lindex沒有-1的話,  

;  vectorvd(a, a+18);  

//元序列輸出  

for(int j=0; j<18; j++)  

coutdouble  sum = sectionmaxsum(vd, 1, vd.size());  

//最大子段和輸出  

couttest();  

return 0;  

最終答案是57.7;可以用在整數和浮點數序列中。

最大欄位和問題 難點分析和C 實現9

給定n個數組成的序列,求其中最大子段和,並規定其中如果所有數均為負值的時候,那麼最大欄位和為零。解決這樣的問題需要用的演算法是 分治法 基本思路 1.劃分兩個長度基本相同的子段,得出以下三種情況 2.如果最大和出現在左邊,就左邊最大子段和為解 3.如果最大和出現在右邊,就右邊最大子段和為解 4.如果...

最大欄位和問題

最大欄位和的思想是將字段分為兩部分,即將陣列平均分為兩部分,那麼最大欄位和的問題分為三種 1 最大欄位和在陣列的第一部分 2 最大欄位和在陣列的第二部分 3 最大欄位和在陣列的 中間 部分,即以陣列的中間數為起點向陣列的兩端擴充套件得到的最大子段和 這個時候就要用到遞迴的思想,最開始就分為這三種情況...

最大欄位和問題

輸入乙個整型陣列,陣列中的乙個或連續多個整數組成乙個子陣列。求所有子陣列的和的最大值。示例1 輸入 nums 2,1,3,4,1,2,1,5,4 輸出 6 解釋 連續子陣列 4,1,2,1 的和最大,為 6。此題很顯然可以用多層for迴圈解決,時間複雜度為o n 2 dp初始化 dp 0 nums ...