Trucks and Cities
题解
二分板子题,虽然老师让我们用区间dp做。
先讲一下二分做法,对于每一辆车,我们已经知道了它在中途的可以加油的次数,故可以二分出每次最多走多少公里就要加一次油,然后就可以得到其油箱的最少容量。
知道了每辆车的最小量,那么总的容量就必须是其中最大的一个。
于是乎就可以用的时间复杂度轻松卡过去了。
其实加上一些小优化就可以更轻松的跑过去了,详情请见代码
源码
火车头其实可以无视掉的
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-vrp")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-fwhole-program")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("inline-functions")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-fstrict-overflow")
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-fcse-skip-blocks")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-fhoist-adjacent-loads")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("inline-small-functions")
#pragma GCC optimize("-finline-small-functions")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("-funsafe-loop-optimizations")
#pragma GCC optimize("inline-functions-called-once")
#pragma GCC optimize("-fdelete-null-pointer-checks")
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
#define gc() getchar()
template<typename _T>
void read(_T &x){
_T f=1;x=0;char s=gc();
while(s>'9'||s<'0'){if(s=='-')f=-1;s=gc();}
while(s>='0'&&s<='9'){x=(x<<3)+(x<<1)+(s^48);s=gc();}
x*=f;
}
template<typename _T>
_T Fabs(_T x){return x<0?-x:x;}
int n,m,a[405],ms[405][405];
int s,t,c,r;LL maxx;
bool check(int x){
int j=s,sum=0;
for(int i=s;i<=t;i++)
if(a[i]-a[j]>x)
j=i-1,sum++;
return sum<=r;
}
signed main(){
read(n);read(m);
for(int i=1;i<=n;i++)read(a[i]);
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
ms[i][j]=max(ms[i][j-1],a[j]-a[j-1]);
for(int i=1;i<=m;i++){
read(s);read(t);read(c);read(r);
int l=ms[s][t],r=a[t]-a[s],num=0;
if(r<=maxx/(1ll*c))continue;
if(l<=maxx/(1ll*c)&&check(maxx/(1ll*c)))continue;
while(l<=r){
int mid=l+r>>1;
if(check(mid))r=mid-1,num=mid;
else l=mid+1;
}
maxx=max(maxx,1ll*num*c);
}
printf("%lld\n",maxx);
return 0;
}