码迷,mamicode.com
首页 > 其他好文 > 详细

[CODE[VS]] P2188 最长上升子序列

时间:2018-01-27 13:47:06      阅读:148      评论:0      收藏:0      [点我收藏+]

标签:pos   gpo   lis   之一   etc   temp   class   包含   har   

题目描述 Description

LIS问题是最经典的动态规划基础问题之一。如果要求一个满足一定条件的最长上升子序列,你还能解决吗?

给出一个长度为N整数序列,请求出它的包含第K个元素的最长上升子序列。

例如:对于长度为6的序列<2,7,3,4,8,5>,它的最长上升子序列为<2,3,4,5>,但如果限制一定要包含第2个元素,那么满足此要求的最长上升子序列就只能是<2,7,8>了。

输入描述 Input Description

第一行为两个整数N,K,如上所述。(80%的数据,满足0<n<=1000,0<k<=n ; 100%的数据,满足0<n<=200000,0<k<=n)

接下来是N个整数,描述一个序列。

输出描述 Output Description

请输出两个整数,即包含第K个元素的最长上升子序列长度。

样例输入 Sample Input

8 6

65 158 170 299 300 155 207 389

样例输出 Sample Output

4

代码

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

using namespace std;

inline int read() {
    int num = 0 , f = 1;
    char ch = getchar();
    while (!isdigit(ch)) {
        if (ch == -) f = -1;
        ch = getchar();
    }
    while (isdigit(ch)) {
        num = num * 10 + ch - 0;
        ch = getchar();
    }
    return num * f; 
}

int n,k,cnt,len = 1;
int temp[200010],line[200010],f[200010],End[200010];

void Binary_Search() {
    for (int i = 2; i <= n; i++) {
        int index = 0;
        int left = 1 , right = len;
        do {
            int mid = (left + right) / 2;
            if (End[mid] < line[i]) {
                left = mid + 1;
                index = mid;
            }
            else 
                right = mid - 1;
        }while (left <= right);
        f[i] = index + 1;
        if (f[i] > len) len = f[i];
        End[f[i]] = line[i];
    } 
}

int main() {
    n = read(); k = read();
    for (int i = 1; i <= n; i++)
        line[i] = read();
    for (int i = 1; i < k; i++) 
        if (line[i] < line[k])
            temp[++cnt] = line[i];
    temp[++cnt] = line[k];
    for (int i = k + 1; i <= n; i++) 
         if (line[i] > line[k])
             temp[++cnt] = line[i];
    n = cnt;
    for (int i = 1; i <= n; i++) 
        line[i] = temp[i];
    End[1] = line[1]; f[1] = 1;
    Binary_Search();
    printf("%d",len);
    return 0;
}

 

[CODE[VS]] P2188 最长上升子序列

标签:pos   gpo   lis   之一   etc   temp   class   包含   har   

原文地址:https://www.cnblogs.com/hkttg/p/8364933.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!