1. 程式人生 > >[CODE[VS]] P2188 最長上升子序列

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

std lis ++ 2個 兩個 整數 spa post 滿足

題目描述 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 最長上升子序列