題目連結:HDU 1003
核心任務:給定整數序列,找出連續子陣列使其和最大,輸出最大和、起始位置、結束位置(1-based 索引)。多測資格式。
維護兩個變數:
current_sum:以當前元素結尾的最大子陣列和max_sum:全域最大和關鍵邏輯:
current_sum += a[i];
if (current_sum > max_sum) {
max_sum = current_sum;
// 更新起終點
}
if (current_sum < 0) {
current_sum = 0; // 捨棄負前綴
temp_start = i + 1; // 新子陣列從下一個開始
}
直觀理解:負數前綴只會拖累後續和,果斷歸零重來。正數前綴則保留延伸。
#include <stdio.h>
#include <string.h>
int main() {
int T, n;
scanf("%d", &T);
for (int tc = 1; tc <= T; ++tc) {
scanf("%d", &n);
int max_sum = -1001; // 題目範圍 -1000~1000
int cur_sum = 0;
int best_l = 1, best_r = 1;
int cur_l = 1;
for (int i = 1; i <= n; ++i) {
int x; scanf("%d", &x);
cur_sum += x;
if (cur_sum > max_sum) {
max_sum = cur_sum;
best_l = cur_l;
best_r = i;
}
if (cur_sum < 0) {
cur_sum = 0;
cur_l = i + 1;
}
}
printf("Case %d:\n%d %d %d\n", tc, max_sum, best_l, best_r);
if (tc != T) printf("\n"); // 題目要求案例間空行
}
return 0;
}
max_sum 必須小於最小可能值(題目 -1000,設 -1001),確保至少選取一個元素n ≤ 100000,O(N) 單掃描完美通過,int 足夠(最大和 1e8)scanf 或自訂快速讀取best_l, best_r 後二次遍歷印出| 指標 | 複雜度 | 說明 |
|---|---|---|
| 時間 | O(N) | 單次線性掃描 |
| 空間 | O(1) | 僅常數額外變數 |
此題是動態規劃/貪心思想的經典入門,掌握「捨棄負前綴」的決策邏輯,即可輕鬆解決所有最大子陣列和變體問題。