luogu P2034 選擇數字

2021-10-03 21:00:17 字數 2165 閱讀 5295

題面傳送門

對於這道題,簡單粗暴的dpdp

dp是不難想的,dpdp

dp方程式為fi=

max(

fj−1

+∑s=

j+1i

as

)f_i=max(f_+\sum_^ia_s)

fi​=ma

x(fj

−1​+

∑s=j

+1i​

as​)

,其中max

(i−k

,0)≤

j≤i−

1max(i-k,0)\leq j\leq i-1

max(i−

k,0)

≤j≤i

−1,然後就有了70

7070

分**實現:

#include

#define max(a,b) ((a)>(b)?(a):(b))

using

namespace std;

long

long n,k,a[

500039

],sum[

500039

],q[

500039

],head,tail,f[

500039

],ans,tot,pus;

intmain()

f[i]

=max

(f[i]

,f[i-1]

);tot=

max(tot,f[i]);

}printf

("%lld\n"

,tot)

;}

考慮字首和優化,設sum

sumsu

m為預處理陣列,dpdp

dp方程式變為fi=

max(

fj+s

umi−

sumj

)f_i=max(f_j+sum_i-sum_j)

fi​=ma

x(fj

​+su

mi​−

sumj

​),可以有80

8080

分。**實現:

#include

#define max(a,b) ((a)>(b)?(a):(b))

using

namespace std;

long

long n,k,a[

500039

],sum[

500039

],q[

500039

],head,tail,f[

500039

],ans,tot,pus;

intmain()

f[i]

=max

(f[i]

,f[i-1]

);tot=

max(tot,f[i]);

}printf

("%lld\n"

,tot)

;}

我們注意到j

jj這一重迴圈在反覆尋找區間最值,那麼想到可以單調佇列優化,這麼一看,似乎是單調佇列板子題:維護乙個單調佇列,每次讓fi−

2+ai

f_+a_i

fi−2​+

ai​入隊並維護單調性,設q為單調佇列,那麼狀態轉移方程:

**實現:

#include

#define max(a,b) ((a)>(b)?(a):(b))

using

namespace std;

long

long n,k,a[

500039

],sum[

500039

],q[

500039

],head,tail,f[

500039

],ans,tot,pus;

intmain()

f[1]=a[1]

; q[

++tail]=0

;for

(i=2

;i<=n;i++

)//for(i=1;i<=n;i++) printf("%lld\n",f[i]);

printf

("%lld\n"

,tot)

;}

題解 lg2034 選擇數字

給定一行n個非負整數a 1 a n 現在你可以選擇其中若干個數,但不能有超過k個連續的數字被選擇。你的任務是使得選出的數字的和最大。設 f i,0 表示考慮到數字 i 並選擇 i 的最大和,f i,1 表示考慮到數字 i 並選擇 i 的最大和 那麼 f i,0 min f i 1,0 f i 1,1...

洛谷P2034 選擇數字

題目描述 給定一行n個非負整數a 1 a n 現在你可以選擇其中若干個數,但不能有超過k個連續的數字被選擇。你的任務是使得選出的數字的和最大。輸入格式 第一行兩個整數n,k 以下n行,每行乙個整數表示a i 輸出格式 輸出乙個值表示答案。乙個小dp 我們設f i 為不選i時候的最優值 然後我寫了個6...

P2034 選擇數字 單調佇列

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