luogu 2627 修建草坪

Posted jack_yyc

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luogu 2627 修建草坪相关的知识,希望对你有一定的参考价值。

题目大意:

一个数列,取出一些数使得它们的总和最大且没有k个连续

思路:

首先我们可以找到一个nk的dp

dp方程:dp[i]=dp[i-1]+sum[i]-sum[j] (sum[j]尽量小)

然后我们可以使用单调队列(单减)优化掉k即简化掉求最小值的一步

技术分享
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<algorithm>
 5 #include<cstring>
 6 #include<cstdlib>
 7 #include<queue>
 8 #include<vector>
 9 #include<set>
10 #include<stack>
11 #define inf 2147483611
12 #define ll long long
13 #define MAXN 100100
14 using namespace std;
15 inline int read()
16 {
17     int x=0,f=1;
18     char ch=getchar();
19     while(!isdigit(ch)) {if(ch==-) f=-1;ch=getchar();}
20     while(isdigit(ch)) {x=x*10+ch-0;ch=getchar();}
21     return x*f;
22 }
23 int n,a[MAXN],k;
24 ll dp[MAXN],s,ans;
25 struct data
26 {
27     ll val,pos;
28 }q[MAXN];
29 int main()
30 {
31     n=read(),k=read();
32     int head=0,tail=1;
33     for(int i=1;i<=n;i++)
34     {
35         a[i]=read();s+=a[i];
36         ll tmp=dp[i-1]-s;
37         while(head<=tail&&q[tail].val<tmp) tail--;
38         q[++tail]=(data) {tmp,i};
39         while(head<=tail&&q[head].pos<i-k) head++;
40         dp[i]=q[head].val+s;
41     }
42     printf("%lld",dp[n]);
43 }
View Code

以上是关于luogu 2627 修建草坪的主要内容,如果未能解决你的问题,请参考以下文章

P2627 修剪草坪

P2627 修剪草坪[dp][单调队列]

修建草坪 单调队列优化DP

BZOJ2442修建草坪(动态规划,单调队列)

luogu P2627 [USACO11OPEN]Mowing the Lawn G 单调队列优化dp

题解 luogu P5021 赛道修建