[CODE[VS]] P2188 最長上升子序列
阿新 • • 發佈:2018-01-27
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; inlineint 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; inttemp[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 最長上升子序列