1. 程式人生 > >noip模擬賽 列車調度

noip模擬賽 列車調度

ont mes sca 格式 noi 包含 www. for stream

【 問題描述 】

有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。

【 輸入格式 】

輸入文件名為manage.in。

輸入共2行。

第 1 行包含1個正整數N,表示N輛列車。

第 2 行包含N個正整數,為1至N的一個排列,表示進站次序。

【 輸出格式 】

輸出文件名為manage.out。

輸出共1行,包含1個整數,表示站臺內軌道數K的最小值。

【 輸入輸出樣例1 】

manage.in

3

1 2 3

manage.out

3

【 輸入輸出樣例2 】

manage.in

9

1 3 2 4 8 6 9 5 7

manage.out

5

【 數據規模與約定 】

對於30%的數據,N≤10;

對於70%的數據,N≤2000;

對於100%的數據,N≤100000。

分析:我O(N^2)的算法竟然A掉了,這數據......

我的做法是每次在已經有列車的軌道上找軌道上最後的比當前標號大的,如果有,就放在它的後邊,否則再單開一個軌道。這樣的原理是i>j,i要在j之前出來,那麽i一定不能放在j後面,所以j就放在i後面就可以了.利用樹狀數組可以優化到O(NlogN).

正解是LIS,和序這道題差不多,把不能放在一起的特征找到.這道題中如果i在j前並且i<j,那麽i,j一定不會放在同一軌道上,那麽O(NlogN)求出LIS就可以了,然而沒我的暴力跑得快233.

#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

typedef long long ll;

int n, a[100010], b[100010], cnt;

int main() { scanf("%d", &n); for (int i = 1; i <= n; i++) scanf("%d", &a[i]); b[++cnt] = a[1]; for (int i = 2; i <= n; i++) { bool flag = false; for (int j = 1; j <= cnt; j++) { if (b[j] > a[i]) { b[j] = a[i]; flag = true; break; } } if (!flag) b[++cnt] = a[i]; } printf("%d\n", cnt); return 0; }

noip模擬賽 列車調度