1090. 绿色通道
题意:
n个题,每个题所花时间为ai,最多只用不超过t分钟做这个,肯定会有题目做不完,下标连续的一些空题称为一个空题段,问在t分钟内最长的空题段至少有多长?
题解:
最长的至少,可以考虑二分
我们二分这个最长的空题段长度len,然后固定这个之后,问题就变成了每len+1个连续的题目至少要选一个题目(因为最长不选区间为len),诶这不就是烽火传递问题了。详细看代码
代码:
#include<bits/stdc++.h>
#define debug(a,b) printf("%s = %d\n",a,b);
typedef long long ll;
using namespace std;inline int read(){int s=0,w=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();//s=(s<<3)+(s<<1)+(ch^48);return s*w;
}
const int maxn=5e5+9;
int a[maxn];
int n,t;
int q[maxn];
int dp[maxn];
bool check(int len){if(len>n)return 1;for(int i=1;i<=n;i++)dp[i]=0,q[i]=0;int hh=0,tt=0;for(int i=1;i<=n;i++){if(q[hh]+len+1<i)hh++;dp[i]=dp[q[hh]]+a[i];while(hh<=tt&&dp[q[tt]]>=dp[i])tt--;q[++tt]=i;}int minn=1e9;for(int i=n;i>=n-len;i--)minn=min(minn,dp[i]);if(minn<=t)return 1;else return 0;
}
int main()
{cin>>n>>t;for(int i=1;i<=n;i++)cin>>a[i];int l=0,r=n;while(l<r){int mid=l+r>>1;if(check(mid))r=mid;else l=mid+1;}cout<<l<<endl;
}