当我们用单调队列优化DP的时候,目前所做的题目都是可以提炼成滑动窗口的形式。然后我们需要考虑一些细节。
1,滑动窗口的端点上我们能不能取到。
2,对于单调队列我们维护的东西是什么?有些单调队列是自然呈上升趋势的。我们单调队列一般维护的都是序列值。
3,我们在DP的过程中是需要先更新值还是先滑动后再更新。因为有时候正向和逆向的时候我们需要先进行滑动才能进行状态转移。
单调队列有时候题意不是很明显的滑动窗口,但是可以通过二分性提炼成滑动窗口的背景。
绿色通道为典型题目的重做。
#include <bits/stdc++.h>
using namespace std;
int m,n;
const int N=1e5+7;
int w[N];
int f[N],q[N];
bool check(int x)
{
memset(f,0,sizeof f);
int tt=0,hh=0;
for(int i=1;i<=n;i++){
if(hh<=tt&&q[hh]<i-x-1) hh++;
f[i]=f[q[hh]]+w[i];
while(hh<=tt&&f[q[tt]]>=f[i])tt--;
q[++tt]=i;
}
int ans=0x3f3f3f3f;
for(int i=n-x;i<=n;i++) ans=min(ans,f[i]);
return ans<=m;
//时间用少了代表空格大了,所以缩小空格
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>w[i];
}
int l=0,r=n;
while(l<r){
// cout<<l<<' '<<r<<endl;
int mid=(l+r)>>1;
if(check(mid)) r=mid;
else l=mid+1;
}
cout<<l<<endl;
}