最长不下降序列(动态规划)

最长不下降序列
查看 提交 统计 提问
总时间限制: 1500ms 内存限制: 65536kB
描述
设有由n个整数组成的数列,任意删掉若干后剩下的数列成为子序列。
如果子序列是严格不递减的,则成为不下降子序列。
求该数列的最长不下降子序列的长度。
并输出一组一组符合要求的最长子序列。
输入
两行
第一行n(1≤n≤10000)
第二行n个数,用空格隔开,范围均在(-1000到1000之间)
输出
两行
第一行:最长子序列长度
第二行:符合要求的一组最长子序列,两个数之间用空格隔开,行末不含空格
样例输入

14
3 7 9 16 38 24 27 38 44 49 21 52 63 15

样例输出

11
3 7 9 16 24 27 38 44 49 52 63

提示
dp

思路点拔:首先,本题是一道经典dp,不管是最长不下降序列,还是什么序列,状态转移方程都是f[i]=max(f[j]+1,f[i]),只是判断条件不相等,我就不全列举了,本题的判断条件为v[i]>=f[j],这样,长度就能对,但是,如何还原一组正解呢?就是从最后一位开始倒退,这样说有点抽象,我们亮一下倒推的代码吧!!

    g[1]=v[t]; //赋初值
    for(int i=2;i<=n;i++) //外层2~n做循环
    {
        for(int j=t;j>1;j--) //内层循环从最长长度开始倒退
        {
            if(v[j-1]<=v[t]&&f[j-1]==f[t]-1) 
            {
                g[i]=v[j-1];  //推出一个正解元素
                t=j-1;//修改t,继续查找下一个正解元素
                break;//结束内层循环
            }
        }
    }

倒推代码出来了,相信用状态转移方程推出最长不下降序列的长度,就完事了~
上完整代码!!!

#include<cstdio>
#include<iostream>
using namespace std;
int v[10005],f[10005]={0,1},g[10005],n,t,maxn;
int main()
{
    scanf("%d",&n); //输入n
    for(int i=1;i<=n;i++)//输入n个元素
    {
        scanf("%d",&v[i]);
    }
    for(int i=2;i<=n;i++)
    {
        f[i]=1; //赋初值
        for(int j=1;j<i;j++)
        {
            if(v[i]>=v[j]) //判断条件
            {
                f[i]=max(f[j]+1,f[i]); //dp(状态转移方程)
            }
        }
    } 
    for(int i=1;i<=n;i++)
    {
        if(f[i]>maxn)
        {
            maxn=f[i]; //计算最长不下降序列的长度
            t=i; //将t的值赋值为i
        }
    }
    g[1]=v[t]; //赋初值
    for(int i=2;i<=n;i++) //外层2~n做循环
    {
        for(int j=t;j>1;j--) //内层循环从最长长度开始倒退
        {
            if(v[j-1]<=v[t]&&f[j-1]==f[t]-1) 
            {
                g[i]=v[j-1];  //推出一个正解元素
                t=j-1;//修改t,继续查找下一个正解元素
                break;//结束内层循环
            }
        }
    }
    printf("%d\n",maxn);
    for(int i=maxn;i>=1;i--) //输出
    {
        printf("%d",g[i]);
        if(i!=1)//养成好习惯,处理一下行末的空格
            printf(" ");
    }
    printf("\n");//换行
    return 0; //完美结束
}

猜你喜欢

转载自blog.csdn.net/qq_42995099/article/details/82055993