有一个长为n的数列a0,a1,...,an-1.请求出这个数列中最长的上升子序列的长度。上升子序列指的是对于任意的 i < j 都满足ai < aj 的子序列。
输入:
5
4 2 3 1 5
输出:
3 (2,3,5)
#include <cstdio>
#include <algorithm>
using namespace std;
int n;
int a[1000];
int dp[1000];
void solve()
{
int res = 0;
for (int i = 0; i < n; i++){
dp[i] = 1;
for (int j = 0; j < i; j++){
if (a[j] < a[i]){
dp[i] = max(dp[i], dp[j] + 1);
}
}
res = max(res, dp[i]);
}
printf("%d\n", res);
}
int main()
{
while (scanf("%d", &n) != EOF){
for (int i = 0; i < n; i++){
scanf("%d", &a[i]);
}
solve();
}
return 0;
}
书中另外给出了的解法使用STL中的low_bound函数降低了时间复杂度。
这里只给出关键代码:
int dp[max_n];
void solve()
{
fill(dp, dp + n, INF);
for (int i = 0; i < n; i++){
*lower_bound(dp, dp + n, a[i]) = a[i];
}
printf("%d\n", lower_bound(dp, dp + n, INF) - dp);
}