bzoj2442 修剪草坪——单调队列
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2442
设 f[i] 为答案,则有 f[i] = max { f[j] - s[j+1] } + s[i] ;
所以用单调队列维护 f[i] - s[i+1];
没有1A!!原因是遍历的起点不是1而是0,因为还可以不选第一个;残念。
代码如下:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; typedef long long ll; int const maxn=1e5+5; int n,k,head,tail; ll f[maxn],s[maxn]; struct N{ll w;int pos;}q[maxn]; int main() { scanf("%d%d",&n,&k); for(int i=1;i<=n;i++) { scanf("%lld",&s[i]);s[i]+=s[i-1]; } head=1;tail=0; for(int i=0;i<=n;i++) { while(head<=tail&&q[head].pos<i-k-1)head++; if(i>k)f[i]=q[head].w+s[i]; else f[i]=s[i]; while(head<=tail&&q[tail].w<=f[i]-s[i+1])tail--; q[++tail].w=f[i]-s[i+1];q[tail].pos=i; } printf("%lld",f[n]); return 0; }