zoukankan      html  css  js  c++  java
  • vijos1369:难解的问题

    描述

    在你的帮助下,蔚蓝来到了埃及.在金字塔里,蔚蓝看到了一个问题,传说,能回答出这个问题的人就能受到埃及法老的祝福,可是蔚蓝日夜奋战,还是想不出来,你能帮帮他么?(XXX: 胡扯,教主怎么可能想不出来= _ =||)(WS这人说的=。=)
    问题是这样的: 
    给定一个序列<a1,a2,...,an>.求最长上升子序列(lis)p1<p2<...<pw满足a[p1]<a[p2]<...<a[pw]
    例如65 158 170 299 300 155 207 389
    LIS=<65,158,170,299,300,389>。

    但是,现在还有一个附加条件:求出的最长上升子序列必须含有第K项。

    比如,在上面的例子中,要求求出的最长上升子序列必须含有第6项,那么最长上升子序列就是:65 155 207 389。

    格式

    输入格式

    第一行是用空格隔开的两个正整数N、K,含义同上所述.
    第二行N个数,即给出的序列.

    输出格式

    仅有一个数,表示含有第K项的最长上升子序列的长度.

    样例输入:
    5 3
    1 2 3 2 1
     
    样例输出:
    3
     
    思路:将第k项左边大于等于第k项的去掉,左边小于等于第k项的去掉。
    #include <iostream>
    #include <algorithm>
    using namespace std;
    const int MAXN=300005;
    const int INF=0x7fffffff;
    int h[MAXN],n,k;
    int a[MAXN],top;
    int dp[MAXN];
    int    lowbound(int l,int r,int val)
    {
        while(r-l>1)
        {
            int mid=(l+r)/2;
            if(dp[mid]>=val)
            {
                r=mid;
            }
            else
            {
                l=mid;
            }
        }    
        return r;
    }
    int main()
    {
        cin>>n>>k;
        k--;
        for(int i=0;i<n;i++)
        {
            cin>>h[i];
            dp[i]=INF;
        }
        for(int i=0;i<k;i++)
        {
            if(h[i]<h[k])
            {
                a[top++]=h[i];
            }
        }
        a[top++]=h[k];
        for(int j=k+1;j<n;j++)
        {
            if(h[j]>h[k])
            {
                a[top++]=h[j];
            }
        }
        for(int i=0;i<top;i++)
        {
            int p=lowbound(-1,top,a[i]);
            dp[p]=a[i];
        }
        int res=lowbound(-1,top,INF);
        cout<<res<<endl;
        return 0;
    }
  • 相关阅读:
    udp和tcp
    以查询代替临时变量
    memcached内存管理
    设计模式适配器模式
    排序算法
    防止表单重复提交
    php的引用
    按位与,按位异或,按位取反
    git常用操作
    http
  • 原文地址:https://www.cnblogs.com/program-ccc/p/5704347.html
Copyright © 2011-2022 走看看