切蛋糕
洛谷P1714 切蛋糕
O(mn)的枚举,按框的长度枚举,A了两个点,TLE了3个。Ans=max(ans,s[i]-s[j]);
#include<bits/stdc++.h> using namespace std; int n,m; long long a[500001],top=1,tail=1,ans=-9999999999; int main() { cin>>n>>m; for(int i=1;i<=n;i++) { cin>>a[i]; a[i]+=a[i-1]; } int si=0; while(si<=m&&(tail-top)<=m) { ans=max(a[tail]-a[top],ans); top++,tail++; if(tail>n) { top=1; si++; tail=si; } } cout<<ans; }
然后进行单调队列优化,ans=max(ans,s[i]-min(s[j));i-m<=j<=i-1;用一个单调递增的单调队列来维护s[j]的最小值,每次直接取队首元素就可以了。如果队尾的位置比当前靠前而且比当前的大,就弹出,如果队尾的位置-队首的位置大于m,从队首弹出。
#include<bits/stdc++.h> using namespace std; int n,m; long long a[500001],top,tai,ans=-9999999999; int q[500001]; int main() { cin>>n>>m; for(int i=1;i<=n;i++) { cin>>a[i]; a[i]+=a[i-1]; } for(int i=1;i<=n;i++) { while(top<=tai&&a[q[tai]]>=a[i]) tai--; while(q[tai]-q[top]>=m) top++; ans=max(ans,a[i]-a[q[top]]); q[++tai]=i; } cout<<ans; }