火車站的列車調度鐵軌的結構如下圖所示。
兩端分別是一條入口(Entrance)軌道和一條出口(Exit)軌道,它們之間有N
條平行的軌道。每趟列車從入口可以選擇任意一條軌道進入,最后從出口離開。在圖中有9趟列車,在入口處按照{8,4,2,5,3,9,1,6,7}的順序排隊等待進入。如果要求它們必須按序號遞減的順序從出口離開,則至少需要多少條平行鐵軌用於調度?
輸入格式:
輸入第一行給出一個整數N
(2 ≤ N
≤105),下一行給出從1到N
的整數序號的一個重排列。數字間以空格分隔。
輸出格式:
在一行中輸出可以將輸入的列車按序號遞減的順序調離所需要的最少的鐵軌條數。
輸入樣例:
9 8 4 2 5 3 9 1 6 7
輸出樣例:
4
分析:出這道題的人的語文成績估計一塌糊塗……
可以這么理解題意:原本,只有一條連接出入口的軌道。現在,由於好幾輛車都不是順序駛入,卻還要求他們降序駛出,所以需要另開出其他軌道供它們 走,使得它們能降序駛出。(但原有軌道應算在結果里)
想讓列車按降序輸出,那么必須讓同一條軌道上的車編號大的先進入,編號小的后進入,而如果一條軌道上編號最小的車的編號如果比要處理的
車的編號還要小的話,那么這個該處理的車就必須新開一條軌道去讓該車進入。
樣例中輸出的結果應該是 8 4 2 1——————
5 3——————————
9 6——————————
7————————————
1、考慮使用二分法
2、使用set容器
先將一個數插入進set容器中,set容器默認從小到大(自動排序);
依次進行每個數的輸入,如果輸入的數比當前set容器中的最后一個數小,刪除set容器中第一個大於輸入數的值,再將輸入數進行插入,
重新排序后,輸入的值就代替了刪除的值,依次循環往復,進行到結尾 。
代碼
二分法做法:
#include<bits/stdc++.h> using namespace std; int main() { int n; scanf("%d",&n); int a[100005]= {0}; //最大到十萬 int i,sum=0; int x; for(i=0;i<n;i++) { scanf("%d",&x); if(sum==0||a[sum-1]<x) //該車比前車大,直接另開新路 { a[sum]=x; sum++; } else //該車比前車小,考慮是跟着前車的路,還是跟着其它比它大的車的路 { //二分查找,找大於該車的最小編碼車 int p=0; int q=sum-1; while(p<q) //直接照搬二分法步驟即可 { int mid=(p+q)/2; if(a[mid]==x) break; else if(a[mid]>x) q=mid-1; else p=mid+1; } a[p]=x; } } printf("%d",sum); }
set做法:
#include<bits/stdc++.h> using namespace std; int main() { int a[100001]={0}; set<int>s; int n; scanf("%d",&n); for(int i=1;i<=n;i++){ cin>>a[i]; } for(int i=1;i<=n;i++){ if(s.upper_bound(a[i])!=s.end()){ s.erase(s.upper_bound(a[i])); s.insert(a[i]); } else s.insert(a[i]); } cout<<s.size(); }
https://blog.csdn.net/qq_40160605/article/details/80150252
https://blog.csdn.net/suguoliang/article/details/88592304