问题链接:http://poj.org/problem?id=2533
最长上升子序列(longest increasing subsequence)
Description
Your program, when given the numeric sequence, must find the length of its longest ordered subsequence.
Input
Output
Sample Input
7 1 7 3 5 9 4 8
Sample Output
4
动态规划
设数组a,Maxlen;
a为输入的序列
Maxlen[k](1<k<n)为以a[k]结束的最长上升子序列的长度(也就是a[0]a[1]a[2]......a[k])
求解以a[n]为终点的序列(a[0],a[1],a[2].....a[n-1],a[n]) 的最长上升子序列的长度,我们可以把他a(n),与a[n-1],a[n-2].......a[2],a[1],a[0]进行比较,如果如果a[n]大于a[n-1],a[n-2].......a[2],a[1],a[0]中的任何一个数,那么Maxlen[n] = Maxlen[k] +1 (1<k<n),求出最大的数,就是以a[n]为终点的LIS。
由此得到状态转移方程:
Maxlen(1) = 1;
Maxlen(k) = max(Maxlen(i) (1 < i < k && a(i) < a(k) && k!= 1) ) +1
这个状态方程的意思是 Maxlen(k)的值就是在 a(k)左边,“终点”数值小于a(k) 且 长度最长的那个lis的长度+1.
结合图和代码会好理解很多
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cctype>
#include<cstring>
using namespace std;
const int Max = 1000;
int main(){
int i,j,n;
int a[Max+10];//输入的序列
int Maxlen[Max+10];//以ai结尾的上升序列的最大长度
memset(Maxlen,0,1000);
cin >> n;
Maxlen[0] = 1;
for(i = 0; i < n; i++){
cin >> a[i];
}
for(i = 1; i < n; i++){
for(j = 0; j < i; j++){
if(a[i] > a[j] && Maxlen[i] < Maxlen[j]+1){
Maxlen[i] = Maxlen[j]+1;
}
}
}
sort(Maxlen,Maxlen+1);//排序
cout<<Maxlen[n-1];
return 0;
}