修剪草坪
f[i][0],f[i][1]表示第i格奶牛选还是不选,
f[i][0]=max(f[i-1][1],f[i-1][0]);
f[i][1]=max(f[j][0]+sum[i]-sum[j]) i-k<=j<i ---> f[i][1]=max(f[j][0]-sum[j])+sum[i] i-k<=j<i 这样就可以用单调队列优化了
这里j<i用先算再加来实现
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 typedef long long ll; 5 const int maxn=1e5+7; 6 ll e[maxn],f[maxn][2],sum[maxn]; 7 ll n,k; 8 int head=1,tail=1,q[maxn]; 9 int main(){ 10 cin>>n>>k; 11 for(int i=1;i<=n;i++) {cin>>e[i];sum[i]=sum[i-1]+e[i];} 12 for(int i=1;i<=n;i++){ 13 f[i][0]=max(f[i-1][0],f[i-1][1]); 14 while(head<=tail&&q[head]<i-k) head++; 15 f[i][1]=f[q[head]][0]-sum[q[head]]+sum[i]; 16 while(head<=tail&&f[i][0]-sum[i]>=f[q[tail]][0]-sum[q[tail]]) tail--; 17 q[++tail]=i; 18 } 19 cout<<max(f[n][0],f[n][1])<<endl; 20 return 0; 21 }
第14行q[head]<i-k是没有等号的