普及- 洛谷 P1115 最大子段和
讀題可知需要在一段一維陣列中尋找一段唯一的區間,使區間內的數和最大,即尋找和最大區間
可以想到字首和的演算法
假設輸入陣列 a[n]
則字首和陣列 b[n]=b[n-1]+a[n]
那麼從什麼時候開始的一段區間才能使區間內的數和最大?
從字首和陣列逐步來判斷這一條件
從 b[1] 開始,當 b[i] 即a的前 i 項字首和 小於 a[i] 時,那麼選取前 i 項 a 的字首和還不如只從 a[i]開始選
這樣就可以得出什麼時候開始的一段區間才能使區間內的數和最大,即從 a 的第 i 項開始
將 b[i] 更新為 a[i],繼續逐步判斷,直到再次找到 b[j] 即a 從 a[i] ~ a[j] 的字首和 小於 a[j] 時
我們可以說選到 a[j] 就足夠了,此時就得到了一個在 a 的第 j 項前的一個區間使區間內的數和最大
將 b[j] 更新為 a[j] ,開啟下一輪尋找和最大區間的操作
重複如上尋找和最大區間的操作,可以將每個和最大區間儲存在一個陣列中
這裡我們採用一種節省空間的辦法:在每次找到和最大區間後,對其進行判斷,若是大於前一個和最大區間,則更新和最大區間
核心程式碼如下:
int a[200010], b[200010];
int main()
{
int n,max1;
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
if (i == 1) max1 = a[i];//初始化和最大區間為第一項
b[i] = max(a[i], b[i - 1] + a[i]);//逐步尋找到邊界值,若b[i]<a[i]則更新b[i]為a[i],否則繼續逐步計算字首和
max1 = max(b[i], max1);//判斷是否為最大的 和最大區間
}
printf("%d", max1);
return 0;
}