1. 程式人生 > >汕頭市隊賽 SRM 07 A 你的麻將會排序嗎

汕頭市隊賽 SRM 07 A 你的麻將會排序嗎

找到 不重復 space 們的 log 技術 機器 == getch

A 你的麻將會排序嗎 SRM 07

曾經有過一些沈迷日麻的小孩紙,後來呀,他們都去尋找自己的世界了。

kpm也是這樣的小孩紙。他想有一只自動整理牌的機器。當麻將以給定的順序進入機器時,通過機器的運轉,使得麻將們出機器的順序是遞增的。所以kpm需要在機器中建立一些傳送帶 (假設這些傳送帶都是足夠長,可以停放很多很多的麻將),問題是,現在kpm需要建立多少條傳送帶才能完成他的機器。

kpm大概有10^5塊麻將吧。

輸入格式

第一行是一個不大於10^5的數,表述麻將的總數。

第二行是麻將依次進入機器的編號,ai表示編號為ai的麻將在i時刻進入機器,保證是一個1-n的排列。

輸入格式

一個數字,表示這個機器最少需要建幾條傳送帶。

樣例輸入

9
8 4 2 5 3 9 1 6 7

樣例輸出

4


這道題其實很容易看出來是求有多少個下降序列(不重復)
就像很多人寫過的導彈攔截一樣 我們可以貪心
每個數x我們都可以找已知的序列中每個序列最末也就是最小的數和x比較 比x大的都符合條件
不過由貪心可得越接近x越好 所以我們的目標其實是找到比x大中最小的
然後我們發現 我們維護的序列具有單調性
比如我們每次找到一個數 x
若序列中沒有符合的 那麽我們會新開一個序列 而這個序列的末端就是x 一定比前面所有的序列末端都大
若找到了j個符合的n-j——n,那麽n-j就是我們要找的最優解 此時x比1-n-j的末端都大 比n-j——n的末端都小 此時用x替換n-j的末端
容易證明序列仍然單調 那麽我們就可以繼續二分了
技術分享
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define LL long long
using namespace std;
const int M=1e5+7;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<0||c>9){if(c==-) f=-1; c=getchar();}
    while(c>=0&&c<=9){ans=ans*10
+(c-0); c=getchar();} return ans*f; } int n,w[M],cnt,k; int find(int k){ int l=1,r=cnt; while(l<=r){ int mid=(l+r)>>1; if(w[mid]<k) l=mid+1; else r=mid-1; } return l; } int main() { n=read(); w[++cnt]=read(); for(int i=2;i<=n;i++){ k=read(); int s=find(k); if(s>cnt) w[++cnt]=k; else w[s]=k; } printf("%d\n",cnt); return 0; }
View Code

汕頭市隊賽 SRM 07 A 你的麻將會排序嗎