https://vjudge.net/problem/Gym-100801J/origin
二分答案出最小距离,dpcheck,单调队列优化dp
#include <iostream> #include <cstdio> #include <queue> #include <algorithm> #include <cmath> #include <cstring> #define inf 2147483647 #define N 1000010 #define p(a) putchar(a) #define For(i,a,b) for(long long i=a;i<=b;++i) using namespace std; long long n,T,l,r,mid,ans; long long p[N],t[N],q[N],f[N]; void in(long long &x){ long long y=1;char c=getchar();x=0; while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();} while(c<='9'&&c>='0'){ x=(x<<1)+(x<<3)+c-'0';c=getchar();} x*=y; } void o(long long x){ if(x<0){p('-');x=-x;} if(x>9)o(x/10); p(x%10+'0'); } bool check(long long x){ long long l=1,r=0; memset(q,0,sizeof(q)); memset(f,0,sizeof(f)); For(i,1,n){ while(l<=r&&q[r]-q[l]>=x) l++; f[i]=f[q[l]]+t[i]; while(l<=r&&f[q[r]]>=f[i]) r--; q[++r]=i; } if(f[n]+n-1<=T) return 1; else return 0; } signed main(){ freopen("journey.in","r",stdin); freopen("journey.out","w",stdout); in(n);in(T); For(i,1,n-1) in(p[i]); For(i,2,n-1) in(t[i]); l=1;r=n; while(l<r){ mid=(l+r)>>1; if(check(mid)) r=mid; else l=mid+1; } ans=p[l]; For(i,l+1,n-1) ans=min(ans,p[i]); o(ans); return 0; }