解题思路:
1.找子问题
首先要确保无后效性,不能将子问题变成“求序列前n个元素的最长上升子序列的长度”,因为可能有多个子序列满足条件,但不能保证每一个子序列最后的元素都满足an<a(n+1),这样就需要考虑这个子序列是怎么来的,所以不具有无后效性。
应该把子问题分解成为“以ak为终点的最长上升子序列长度”,将n个子问题解决,原问题也解决。
2.确定状态
N个状态
3.找出转移方程:
maxLen(k)表示以ak做为终点的最长上升子序列的长度。
初始状态:max{maxLen(i):1<=i<k且ai<ak且k≠1}+1
若找不到这样的i,则maxLen(k)=1
maxLen(k)的值就是在ak左边,终点数值小于ak,且长度最大的那个最长上升子序列的长度再加1,因为任何ak左边终点小于ak的最长上升子序列加上ak就能形成更长的上升子序列。
代码:
const int MAXN=1010;
int a[MAXN];
int maxLen[MAXN];
int main()
{
int N; cin>>N;
for(int i=1;i<=N;i++)
{
cin>>a[i]; maxLen[i] = 1;
}
for(int i =2;i<=N;i++)
{
for(int j =1;j<i;j++)
{
if(a[i]>a[j])
maxLen[i] = max{maxLen[i],maxLen[j]+1;
}
}
cout<<*max_element(maxLen+1,maxLen+N+1);
return 0;
}