L2-014. 列车调度
这是一道比较有意思的题。思路很简单,重点在于做好优化。
解题思路: 通过轨道进行调度,想要让车按照序号降序开出,问你最少需要多少轨道。 首先我们知道要想让车按照降序开出的话,每个在轨道上车的序号都要小于同轨道前面车的序号。 那么我们,每读取一辆车的序号,都要拿着该序号和所有轨道上最后一辆车的序号去比,只有该车序号小于某轨道上最后一辆车的序号,才能把该车停到该轨道上。 最适合停靠的是最后一辆车的序号和该车序号差值最小的轨道。 如果没有任何一条可以满足停该车条件的轨道,就要多创建一条轨道。 我们可以贪心一下,只要该车能停进现有的任何一个轨道,就不为其创建新的轨道。
思路有了接下来就是优化的问题了。 开数组a[100010],a[i]保存第i+1轨道上停的最后一辆车的id(序号)。 我们可以发现,当我们创建新轨道时都是由于之前每一条轨道上的最后一辆车的序号都小于你要停的车的序号。 意味着 其满足 a[i+1]>a[i]; 所以读入每个车的id。都先拿该id和a[n-1]比较。如果大于它,那么现有的任何轨道都不满足该车的停靠条件。 如果小于它,根据a[i+1]>a[i],我们可以通过二分查找,确定最适合停靠的轨道。
#include <cstdio> #include <cstring> #include <algorithm> #include <math.h> using namespace std; const int MAX=1e5+10; int a[MAX]; void updata(int x,int l,int r) { if(l==r) { a[l]=x; return; } int mid=(l+r)/2; if(a[mid]>x) { updata(x,l,mid); } else { updata(x,mid+1,r); } } int main() { int T,n,x; scanf("%d",&T); n=0; while(T--) { scanf("%d",&x); if(n==0) a[n++]=x; else if(x>a[n-1]) { a[n++]=x; } else { updata(x,0,n-1); } } printf("%d\n",n); return 0; }