題面傳送門
對於這道題,簡單粗暴的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 輸出乙...