分析:
(1)笨方法,我們可以用普通最大子段和的方法解決這個問題。我們從每個位置「斷開」環,然後按普通的最大子段和的方法去做。這樣做的複雜度是o(n^2)。
(2)巧妙點的方法,我們之所以要從某個位置切開是因為迴圈的最大子段和可能是跨越一部分頭和尾。
如上圖,最優解可能是0..i, j + 1.. n – 1兩段,那這時,其實中間i + 1..j是個「最小子段和」,因為總和是一定得嘛。
所以「迴圈陣列得最大子段和」問題,可以把環從任意位置斷開,然後求出最優解 = max(普通的最大子段和, 總和 – 普通的「最小子段和」)
求最小子段和,顯然也可以用最大子段和的方法求一次就可以了。所以迴圈陣列的最大子段和,實際上是求了兩次最大子段和而已。
accode:
#include #include #include #include #include #include #include #include #define maxn 50005
#define ll long long
using namespace std;
int n,m;
ll c[maxn];
ll max_ans,min_ans,tmp,sum;
int main()
tmp=0;
for(int i=1;i<=n;++i)
printf("%i64d\n",max(max_ans,sum-min_ans));
}return 0;
}
51nod 迴圈陣列最大子段和
這個問題就是在原來的基礎上加上了可以迴圈。那麼我們可以分兩種情況處理,一種是有從尾到頭的,例如1表示取,0表示不取,則是11000011 一種是沒有跨越的,即000111100 那麼對於第二種情況可以直接用最大欄位和做,關鍵是第一段要怎麼處理。這裡需要用到逆向思維,在1110000111這乙個答案中...
51nod 迴圈陣列最大子段和 dp
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 最大子段和
給出乙個整數陣列a 正負數都有 如何找出乙個連續子陣列 可以乙個都不取,那麼結果為0 使得其中的和最大?例如 2,11,4,13,5,2,和最大的子段為 11,4,13。和為20。輸入 第1行 整數序列的長度n 2 n 50000 第2 n 1行 n個整數 10 9 a i 10 9 輸出 輸出最大...