n個整數組成的迴圈序列a[1],a[2],a[3],…,a[n],求該序列如a[i]+a[i+1]+…+a[j]的連續的子段和的最大值(迴圈序列是指n個數圍成乙個圈,因此需要考慮a[n-1],a[n],a[1],a[2]這樣的序列)。當所給的整數均為負數時和為0。
例如:-2,11,-4,13,-5,-2,和最大的子段為:11,-4,13。和為20。
input
第1行:整數序列的長度n(2 <= n <= 50000)output第2 - n+1行:n個整數 (-10^9 <= s[i] <= 10^9)
輸出迴圈陣列的最大子段和。input示例
6output示例-211
-413
-5-2
20
題目其實就是求出下標i,j,使得sum[j]-sum[i]最大,只要列舉每個j然後找到符合的最小的sum[i]就可以。這裡既然是迴圈的陣列,就需要擴充兩倍長度,但是所求的結果顯然不能j-i超過n,所以考慮單調佇列,front端到back端保證單調sum[x]單調遞增。每次列舉先把超過長度的pop掉,然後更新,再維護單調性地插入sum[i]即可。
#include using namespace std;
typedef long long ll;
const int maxn = 5e4 + 10;
ll a[maxn * 2], sum[maxn * 2];
int main()
sum[0] = 0;
for (int i = 1; i <= 2 * n; i++)
sum[i] = sum[i - 1] + a[i];
ll ans = 0;
deque que;
que.push_back(0);
for (int i = 1; i <= 2 * n; i++)
printf("%i64d\n", ans);
return 0;
}
51nod 1050 迴圈陣列最大和
感覺自己的碼力還很差 思維愚鈍 一開始把他搞成2倍長度來做 然後列舉每乙個始點加長度為n的陣列跑乙個dp 這樣複雜度高達o n 2 實際上我們可以分析一下 這個max有可能在1 n內取到 也有在迴圈陣列中取到 所以我們先跑一段1 n的dp 記為ans1 然後我們跑一段迴圈陣列內的dp 記為ans2 ...
51nod 1050 迴圈陣列最大子段和
n個整數組成的迴圈序列a 1 a 2 a 3 a n 求該序列如a i a i 1 a j 的連續的子段和的最大值 迴圈序列是指n個數圍成乙個圈,因此需要考慮a n 1 a n a 1 a 2 這樣的序列 當所給的整數均為負數時和為0。例如 2,11,4,13,5,2,和最大的子段為 11,4,13...
51nod 1050 迴圈陣列最大子段和
51nod 1050 迴圈陣列最大子段和 最大子段和的公升級版,有乙個可以迴圈的子段,也就是首尾可以相連,如果首尾相連,那麼中間空出來的一段就是應該是最小字段和。那麼答案應該是從原版得出的值和首尾相接得出的值取最大的即可。include include include include include...