题目大意:
现只有一个测例,测例中给出一个长度为N(1 ≤ N ≤ 1,000)的乱序序列,序列中元素为[0, 10000],现求最长的严格上升子序列的长度(该子序列后一个值一定大于前一个值),比如1 7 3 5 9 4 8中最长上升子序列为1 3 5 8,长度为4,但是该子序列不一定唯一,也可以是1 3 4 8。
注释代码:
/*
* Problem ID : POJ 2533 Longest Ordered Subsequence
* Author : Lirx.t.Una
* Language : C++
* Run Time : 0 ms
* Run Memory : 148 KB
*/
#include <algorithm>
#include <iostream>
#include <cstdio>
using namespace std;
//元素的无穷大
//无穷小取-1
#define INF 10001
//元素最大个数留位置给-1和INF
#define MAXN 1002
//范围处在short内
short dp[MAXN];
int
main() {
int n;//元素个数
int i;//计数变量
int x;//接受每一个元素
int len;//当前最长上升子序列长度
scanf("%d", &n);
//初始化
dp[0] = -1;
dp[1] = INF;
len = 0;
while ( n-- ) {
scanf("%d", &x);
//找出≥x的第一个元素在dp数组中的下标
i = lower_bound(dp, dp + len + 1, x) - dp;
dp[i] = x;
if ( i == len + 1 ) {
len++;
dp[len + 1] = INF;
}
}
printf("%d\n", len);
return 0;
}
无注释代码:
#include <algorithm>
#include <iostream>
#include <cstdio>
using namespace std;
#define INF 10001
#define MAXN 1002
int dp[MAXN];
int
main() {
int n;
int i;
int x;
int len;
scanf("%d", &n);
dp[0] = -1;
dp[1] = INF;
len = 0;
while ( n-- ) {
scanf("%d", &x);
i = lower_bound(dp, dp + len + 1, x) - dp;
dp[i] = x;
if ( i == len + 1 ) {
len++;
dp[len + 1] = INF;
}
}
printf("%d\n", len);
return 0;
}