题目:修剪草坪
思路:dp,用单调队列优化转移。
代码:
#include<bits/stdc++.h>
using namespace std;
#define maxn 100000
#define ll long long
int n,k;
ll a[maxn+5];
ll f[maxn+5],que[maxn+5];
int h=0,t=0;
void read(int& x) {
scanf("%d",&x);
}
void read(ll& x) {
scanf("%lld",&x);
}
void init() {
for(int i=1; i<=n; i++) a[i]+=a[i-1];
}
ll dp() {
init();
f[1]=a[1];
for(int i=2; i<=n; i++) {
while(t>h&&i-que[h]>k) h++;
f[i]=f[que[h]-1]-a[que[h]]+a[i];
while(t>=h&&f[que[t]-1]-a[que[t]]<f[i-1]-a[i]) t--;
que[++t]=i;
}
ll ans=0;
for(int i=1; i<=n; i++) ans=max(ans,f[i]);
return ans;
}
ll find() {
ll ans=0;
for(int i=1;i<=n;i++) {
f[i]=max(f[i-2],f[i-3])+a[i];
ans=max(ans,f[i]);
}
return ans;
}
int main() {
read(n);
read(k);
for(int i=1; i<=n; i++) read(a[i]);
ll ans;
if(k==1) ans=find();
else ans=dp();
printf("%lld",ans);
return 0;
}