汕头市队赛 SRM 07 A 你的麻将会排序吗

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

 

转载于:https://www.cnblogs.com/lyzuikeai/p/7207768.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值