1≤n,m≤300000
輸入樣例:
6 41 -3 5 1 -2 3
輸出樣例:
7思路:顯然我們要在字首和陣列中sum[i]的前m範圍內找到乙個min,那麼以第i個數結尾的m個連續元素的序列的最大子序和就是這個sum[i]-min;最後就只需要遍歷一遍尋找答案啦。顯然在尋找min的時候我們也可以迴圈列舉,但這樣的時間複雜度就會很高啦;這個時候我們就可以優化一下,用乙個佇列存m範圍內的數(不對彈出和加入來維護),而且如果佇列**現』大小』的兩個數,那麼前面那個大的數就永遠不會用到(比小數先彈出,又不是min)所有整個佇列就變成乙個嚴格單調的佇列了,而且隊頭就是我們尋找的min.
**實現:
#include
#include
using
namespace std;
typedef
long
long ll;
const
int n =
3e5+5;
int n, m;
int q[n]
;ll s[n]
;int
main()
int hh =
0, tt =0;
ll res = int_min;
for(
int i =
1; i <= n; i ++
) cout << res << endl;
return0;
}
最大子序和 單調佇列
輸入乙個長度為n的整數序列,從中找出一段長度不超過m的連續子串行,使得子串行中所有數的和最大。輸入格式 第一行輸入兩個整數n,m。第二行輸入n個數,代表長度為n的整數序列。同一行數之間用空格隔開。輸出格式 輸出乙個整數,代表該序列的最大子序和。資料範圍 1 n,m 300000 輸入樣例 6 4 1...
最大子序和(優先佇列 字首和)
輸入乙個長度為n的整數序列,從中找出一段不超過m的連續子串行,使得整個序列的和最大。先用s um sumsu m 存一下序列的字首和 我們需要找到乙個最大的sum r sum l r l m sum r sum l r l m sum r sum l r l m 拿雙端佇列維護 最優解的情況就是下標...
最大子序和
演算法一 對這個問題,有乙個相對複雜的 o nlogn 的解法,就是使用遞迴。如果要是求出序列的位置的話,這將是最好的演算法了 因為我們後面還會有個 o n 的演算法,但是不能求出最大子串行的位置 該方法我們採用 分治策略 divide and conquer 在我們例子中,最大子串行可能在三個地方...