77. 最长严格上升子序列(动态规划)

1576 最长严格上升子序列

 

 时间限制: 1 s
 空间限制: 256000 KB
 题目等级 : 黄金 Gold
题目描述 Description

给一个数组a1, a2 ... an,找到最长的上升降子序列ab1b2< .. bk,其中b1

输出长度即可。

输入描述 Input Description

第一行,一个整数N。

第二行,N个整数(N 5000)

输出描述 Output Description

输出K的极大值,即最长不下降子序列的长度

样例输入 Sample Input

5

7

样例输出 Sample Output

3

数据范围及提示 Data Size & Hint

【样例解释】

最长不下降子序列为3,6,7

分类标签 Tags 点此展开 

算法分析:
        根据动态规划的原理,由后往前进行搜索(当然从前往后也一样)
       b(n)来说,由于它是最后一个数,所以当从b(n)开始查找时,只存在长度为1的不下降序列;
        若从b(n-1)开始查找,则存在下面的两种可能性:
         b(n-1)则存在长度为2的不下降序列b(n-1)b(n)
         b(n-1)>b(n)则存在长度为1的不下降序列b(n-1)b(n)
        一般若从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;
}
原文地址:https://www.cnblogs.com/csgc0131123/p/5290313.html