20241016每日一題洛谷P1115

才瓯發表於2024-10-16

普及- 洛谷 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;
}

相關文章