最长上升子序列(线性DP)

-->测评传送门

题目描述
给定一个数列求其最长上升子序列

输入格式
输入第一行一个整数n 第二行n个整数

输出格式
输出max=长度 以及最长上升子序列(若存在多解情况,那么输出对应编号字典序最小的那个)


样例输入
14
13 7 9 16 38 24 37 18 44 19 21 22 63 15
样例输出
max=8
7 9 16 18 19 21 22 63
数据范围与提示
n<=100


光求长度很容易,但记录路径就麻烦了(至少我想一下午没想出来)

解析:

  • 记录长度很容易,从前往后扫一遍,记录每次 1~i 的最大长度
  • 于此同时,另开一个数组结构体,(或一个二维数组)记录路径,为了复制方便,推荐用结构体哦

一看代码就懂啦:

#include<stdio.h>
#include<algorithm>
using namespace std;
struct qu{
    int l[101];
}line[101];
int a[101],f[101];

int main()
{
    int n,aim,ans=1;
    scanf("%d",&n);
    for(int i=1;i<=n;++i)
    scanf("%d",&a[i]);
    
    for(int i=1;i<=n;++i)
    {
        f[i]=1;
        line[i].l[1]=a[i];
        for(int j=1;j<i;++j)
        {
            if(a[j]<a[i] && f[j]+1>f[i])
            {
                f[i]=f[j]+1;
                line[i]=line[j];
                line[i].l[f[i]]=a[i];
            }
        }
        if(ans<f[i])
        {
            ans=f[i];
            aim=i;
        }
    }
    printf("max=%d\n",ans);
    for(int i=1;i<=ans;++i)
        printf("%d ",line[aim].l[i]);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/qseer/p/9429719.html