题目描述 Description
给一个数组a1, a2 ... an,找到最长的上升降子序列ab1b2< .. bk,其中b1
输出长度即可。
输入描述 Input Description
第一行,一个整数N。
第二行,N个整数(N < = 5000)
输出描述 Output Description
输出K的极大值,即最长不下降子序列的长度
样例输入 Sample Input
5
9 3 6 2 7
样例输出 Sample Output
3
数据范围及提示 Data Size & Hint
【样例解释】
最长不下降子序列为3,6,7
分类标签 Tags 点此展开
㈡算法分析:
根据动态规划的原理,由后往前进行搜索
(
当然从前往后也一样
)
。
1·
对
b(n)
来说,由于它是最后一个数,所以当从
b(n)
开始查找时,只存在
长度为
1
的不下降序列;
2·
若从
b(n-1)
开始查找,则存在下面的两种可能性:
①
若
b(n-1)则存在长度为2的不下降序列b(n-1),b(n)。
②
若
b(n-1)>b(n)
则存在长度为
1
的不下降序列
b(n-1)
或
b(n)
。
3·
一般若从
b(i)
开始,此时最长不下降序列应该按下列方法求出
:
在
b(i+1),b(i+2),…,b(n)
中,找出一个比
b(i)
大的且最长的不下降序列,作为它的
后继。
㈢
数据结构:
为算法上的需要,定义一个整数类型二维数组
b(N,3)
1·b(I,1)
表示第
I
个数的数值本身;
2·b(I,2)
表示从
I
位置到达
N
的最长不下降序列长度
㈤一般处理过程是:
①在i+1,i+2,…,n项中,找出比b[I,1]大的最长长度L以及位置K;
②若L>0,则b[I,2]:=L+1;b[I,3]:=k;
代码:
#include
using namespace std;
#include
int a[5001][3],n;//a[i][1]储存原数,a[i][2]储存1-i的最长上升子序列
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;++i)
{
scanf("%d",&a[i][1]);
a[i][2]=1;//把初始序列长度设为1
}
for(int i=1;i<=n;++i)
{
int maxx=1;//注意
for(int j=1;j
{
if(a[j][1]
maxx)
{
maxx=a[j][2]+1;
}
}
a[i][2]=maxx;
}
int lon=0;
for(int i=1;i<=n;++i)
{
if(a[i][2]>lon)//找出最长长度
lon=a[i][2];
}
cout<<lon<<endl;
return 0;
}