單調佇列優化DP P2034 選擇數字

2022-02-18 01:32:18 字數 1374 閱讀 6730

給定一行n個非負整數a[1]..a[n]。現在你可以選擇其中若干個數,但不能有超過k個連續的數字被選擇。你的任務是使得選出的數字的和最大。

輸入格式

第一行兩個整數n,k

以下n行,每行乙個整數表示a[i]。

輸出乙個值表示答案。

5 2123

45對於20%的資料,n <= 10

對於另外20%的資料, k = 1

對於60%的資料,n <= 1000

對於100%的資料,1 <= n <= 100000,1 <= k <= n,0 <= 數字大小 <= 1,000,000,000

時間限制500ms

一般正常求序列幾段和都要求字首和,f的第一維都是前i項的最優值

那我們直接開始吧,

f[i]=max(f[j])+a[i] ( i-k<=j然鵝叫上去可能只對兩個點(可能連樣例都不過),原因是方程都錯了,少了一維,i不一定選取就是最佳選擇,如1 8 4 2 999 k=2,顯然不選4要更優, 所以正確的轉移方程:

//0表示不選第i個數,1表示選第i個數

f[0][i]=max(f[0][i-1],f[1][i-1]);

f[1][i]=max(f[0][j]-sum[j])+sum[i];

親測o(n*n)+快讀能壓線過

所以考慮優化

我們用單調佇列維護f[0][j]-sum[j]的最優值,因為它完全符合單調性,維護就完事

/*#!/bin/sh

dir=$gedit_current_document_dir

name=$gedit_current_document_name

pre=$

g++ -o2 $dir/$name -o $pre -g -wall -std=c++11

if test $? -eq 0; then

gnome-terminal -x bash -c "time $dir/$pre;echo;read;"

fi*/

#include#include#include#include#includeusing namespace std;

const int maxn=1e6+5,inf=0x3f3f3f3f;

inline int read();

while(ch>='0'&&ch<='9')s=s*10+ch-'0',ch=getchar();

return s*w;

}int n,d,a[maxn],head=1,tail;

long long sum[maxn],f[2][maxn],q[maxn];//每個數有1e9誒

int main()

cout<}

P2034 選擇數字 單調佇列

p2034 選擇數字 單調佇列 gyro永不抽風 最後更新 2020年09月20日 21 09 許可協議 給定一行n個非負整數a 1 a n 現在你可以選擇其中若干個數,但不能有超過k個連續的數字被選擇。你的任務是使得選出的數字的和最大。第一行兩個整數n,k 以下n行,每行乙個整數表示a i 輸出乙...

單調佇列優化

單調佇列是一種嚴格單調的佇列,可以單調遞增,也可以單調遞減。隊首位置儲存的是最優解,第二個位置儲存的是次優解。單調佇列可以有兩個操作 1 插入乙個新的元素,該元素從隊尾開始向隊首進行搜尋,找到合適的位置插入之,如果該位置原本有元素,則替換它。2 在過程中從隊首刪除不符合當前要求的元素。單調佇列實現起...

單調佇列 優化DP

佇列元素保持單調遞增 減 而保持的方式就是通過插隊,把隊尾破壞了單調性的數全部擠掉,從而使佇列元素保持單調。單調佇列的作用 優化dp。許多單調佇列優化的dp可以使複雜度直接降維,下面就以最簡單的一道題為例 在某兩座城市之間有 n 個烽火台,每個烽火台發出訊號都有一定代價。為了使情報準確地傳遞,在連續...