最长上升子序列

解题思路:

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;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值