LIS:
dp[i]含义:以下标为i的元素为结尾的最长上升子序列的长度
dp[]初始化为1
dp[i] = max(dp[j]+1){其中0<j<i且a[j]<a[i]}
最后结果为max{dp[i],0<i<=n}
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 1005
using namespace std;
int a[N];
int dp[N];
int n;
int main()
{
//freopen("e:\\input.txt", "r", stdin);
while (scanf("%d", &n) != EOF)
{
memset(dp, 0, sizeof(dp));
for (int i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
dp[i] = 1;//初始化dp数组
}
for (int i = 2; i <= n; i++)
{
for (int j = 1; j < i; j++)
{
if (a[j] < a[i])
dp[i] = max(dp[i], dp[j] + 1);//状态方程
}
}
int ans = 0;
for (int i = 1; i <= n; i++)
ans = max(ans, dp[i]);
printf("%d\n", ans);
}
return 0;
}
还有一种复杂度为O(n方)的算法:
另取一数组存储原序列,对其排序,在求出它与原序列的最长公共子序列
第三种方法:dfs
#include<iostream>
#include<stack>
using namespace std;
int n;
int* a;
stack<int> s;
int count=0;
int best=0;
void dfs(int i)
{
if(i==n)
{
if(s.size()>best) best=s.size();
return;
}
if(s.empty()||a[i]>s.top())
{
s.push(a[i]);
dfs(i+1);
s.pop();
}
if(s.size()+n-i-1>best) dfs(i+1);
}
int main()
{
while(cin>>n)
{
int i;
a=new int[n];
for(i=0;i<n;i++)
{
cin>>a[i];
}
dfs(0);
cout<<best<<endl;
delete [] a;
}
return 0;
}
还有一种复杂度为O(nlogn)的算法,本人能力有限,目前尚未搞清楚,用户可到其他博客上进行查找学习