【SOJ 1823】列车调度

【题目】

题目描述:

有 N 辆列车,标记为 1,2,3,…,N。它们按照一定的次序进站,站台共有 K 个轨道,轨道遵从先进先出的原则。列车进入站台内的轨道后可以等待任意时间后出站,且所有列车不可后退。现在要使出站的顺序变为 N,N-1,N-2,…,1,询问 K 的最小值是多少。

    

例如上图中进站的顺序为 1,3,2,4,8,6,9,5,7,则出站的顺序变为 9,8,7,6,5,4,3,2,1。

输入格式:

输入共 2 行。
第 1 行包含 1 个正整数 N ,表示 N 辆列车。
第 2 行包含 N 个正整数,为 1 至 N 的一个排列,表示进站次序。

输出格式:

输出共 1 行,包含 1 个整数,表示站台内轨道数 K 的最小值。

样例数据:

输入
3
1 2 3

输出
3

输入
9
1 3 2 4 8 6 9 5 7

输出
5

备注:

【数据规模与约定】
对于 30% 的数据,N ≤ 10;
对于 70% 的数据,N ≤ 2000;
对于 100% 的数据,N ≤ 100000。

【分析】

第一次 A 第二题

感觉这道题有点像最长下降子序列,听说大佬们还用这个方法做出来了,这里本蒟蒻说一下贪心的算法

对于每一个轨道,由于是先进先出,出站的顺序又是从 N 到 1,很明显,每一个轨道后进入的列车的编号一定比前面的小

我们可以把原问题转换成,将这个序列分割成几个下降的序列,且数量要尽可能少

例如样例数据 2,我们可以把它拆成(1),(3,2),(4),(8,6,5),(9,7)

我们用一个数组记录每个轨道进来的最后一个列车的编号,每次新进来一辆列车,就找数组中大于它的最小的那个轨道,将它加到这个轨道中。这样的话,我们就能保证数组中的数单调递增,就可以用二分

【代码】

#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 100005 
using namespace std;
int a[N],track[N];
int main()
{
//  freopen("manage.in","r",stdin);
//  freopen("manage.out","w",stdout);
    int n,i,l,r,mid,k=1;
    scanf("%d",&n);
    for(i=1;i<=n;++i)
      scanf("%d",&a[i]);
    track[1]=a[1];
    for(i=2;i<=n;++i)   
    {
        l=1,r=k;
        if(track[k]<a[i])
        {
        	k++;
        	track[k]=a[i];
        	continue;
        }
        while(l<r)
        {
        	mid=(l+r)>>1;
        	if(track[mid]>a[i])  r=mid;
        	else  l=mid+1;
        }
        track[l]=a[i];
    }
    printf("%d",k);
//  fclose(stdin);
//  fclose(stdout);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/forever_dreams/article/details/81254072
今日推荐