Bootstrap

NOI / 2.6基本算法之动态规划——1759:最长上升子序列

总时间限制: 2000ms    内存限制: 65536kB

描述

一个数的序列bi,当b1 < b2 < ... < bS的时候,我们称这个序列是上升的。对于给定的一个序列(a1a2, ..., aN),我们可以得到一些上升的子序列(ai1ai2, ..., aiK),这里1 <= i1 < i2 < ... < iK <= N。比如,对于序列(1, 7, 3, 5, 9, 4, 8),有它的一些上升子序列,如(1, 7), (3, 4, 8)等等。这些子序列中最长的长度是4,比如子序列(1, 3, 5, 8).

你的任务,就是对于给定的序列,求出最长上升子序列的长度。

输入

输入的第一行是序列的长度N (1 <= N <= 1000)。第二行给出序列中的N个整数,这些整数的取值范围都在0到10000。

输出

最长上升子序列的长度。

样例输入

7
1 7 3 5 9 4 8

样例输出

4

来源

翻译自 Northeastern Europe 2002, Far-Eastern Subregion 的比赛试题

下面介绍2种思路:

思路一:状态定义为以i为开头或结尾的最长上升子序列的长度

写法1:状态定义为以i为开头的最长上升子序列的长度(原作者:Trigger_G,按本作者的编程习惯略微改动,侵删)

内存:248kB    时间:12ms

/*作者:Trigger_G*/
/*written by Trigger_G*/
/*来自网站:https://blog.csdn.net/qq_36006682/article/details/102755984*/
#include<bits/stdc++.h>
using namespace std;
int a[1001],b[1001];
int maxx=0,point,n;
int main()
{
	cin>>n;
	for(int p=1;p<=n;p++)b[p]=1;
	for(int i=1;i<=n;i++)cin>>a[i];
	for(int i=n-1;i>=1;i--)for(int j=i;j<=n;j++)if(a[i]<a[j]&&b[i]<=b[j])b[i]=b[j]+1;
	for(int i=1;i<=n;i++)if(b[i]>maxx)maxx=b[i];
	cout<<maxx;
	return 0;
}

 写法2:状态定义为以i为结尾的最长上升子序列的长度(原创)

内存:276kB    时间:8ms

/*作者:宇宙猎手*/
/*written by Yu Zhou Hunter*/
#include<bits/stdc++.h>
using namespace std;
int a[1000],b[1000],m,n;
int main()
{
	cin>>m;
	for(int i=0;i<m;i++)
	{
		cin>>a[i];
		for(int j=0;j<i;j++)if(a[i]>a[j]&&b[i]<=b[j])b[i]=b[j]+1;
		if(b[i]>n)n=b[i];
	}
	cout<<n+1;
	return 0;
}

思路二:贪心算法(原作者:君义_noip,按本作者的编程习惯略微改动,侵删)

内存:280kB    时间:10ms

/*作者:君义_noip*/
/*written by 君义_noip*/
/*来自网站:https://blog.csdn.net/lq1990717/article/details/124136872*/
#include<bits/stdc++.h>
using namespace std;
int n,a[1001],d[1001],len;
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)cin>>a[i];
    len++;
    d[len]=a[1];
    for(int i=2;i<=n;i++)
    {
        if(a[i]>d[len])len++,d[len]=a[i];
        else
        {
            int l=1,r=len;
            while(l<r)
            {
                int m=(l+r)/2;
                if(d[m]>=a[i])r=m;
                else l=m+1;
            }
            d[l]=a[i];
        }
    }
    cout<<len;
    return 0;
}

 已访问过其它网站,解法与此大同小异。

若有新解法,欢迎在评论区讨论。

;