最长上升子序列是一种线性结构上的动态规划
1 复杂度为o(n*n)的算法
设d(i)为以a[i]为结尾的最长上升子序列的长度,则d(i) = max {0 , d(j) | j < i && a[j] < a[i] } + 1 , 最终答案为 max{d(i)} 。
代码为:
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
using namespace std;
const int maxn = 105 ;
int a[maxn] , dp[maxn] ;
int LCS(int n)
{
int maxLen = 1 ;
dp[1] = 1 ;
for(int i = 2 ; i <= n ; i ++)
{
dp[i] = 1 ;
for(int j = 1 ; j < i ; j ++)
if(a[j] < a[i]) dp[i] = max(dp[i] , dp[j] + 1) ;
if(dp[i] > maxLen) maxLen = dp[i] ;
}
return maxLen ;
}
2 复杂度为o(nlogn)的算法
设dp[i]:= 长度为i + 1 的上升子序列中末尾元素的最小值(不存在的话就是INF)
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
using namespace std;
const int maxn = 105 , INF = 1e9;
int a[maxn] , dp[maxn] , 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 ) ;
}