zoukankan      html  css  js  c++  java
  • JDOJ 1946 求最长不下降子序列个数

    Description

    设有一个整数的序列:b1,b2,…,bn,对于下标i1<i2<…<im,若有bi1≤bi2≤…≤bim
    则称存在一个长度为m的不下降序列。

    现在有n个数,请你求出这n个数的最长不下降序列的长度及有多少个最长不下降序列

    Input

    第一行为一个整数n (n < 104

    第二行有n个整数,数与数之间使用空格间隔

    Output

    第一行,最长不下降序列的长度

    第二行,能构成多少个最长不下降序列(数字相同,位置不同算不同)

    Sample Input

    7 1 4 3 2 6 5 7

    Sample Output

    4 6 
     
    这道题综合了求最长不降子序列长度和个数,是一道不折不扣的好题。
    需要一定的动归基础,0基础同学请自动回避本博客。
     
    定义两个数组,dp数组表示以i结尾的最长不降子序列长度,
    len数组表示以i结尾的最长不降子序列的个数。
     
    我们处理第一问的时候,在输出上加一些处理。
    求最长不降子序列的时候,先初始化dp[i]=1;不需要解释。
    然后内层循环从1到i-1开始扫。如果符合条件(a[j]<=a[i])
    就转移,dp[i]取dp[i]和dp[j]+1的较大值。
    这些都不需要解释,。
    然后定义标记变量vis,初值一定要设置1。
    从头扫,不断更新最长的长度。
    最后求出最最最长的长度dp[vis]输出。
     
    然后是本题的重头戏。
    第二次动归。
    首先是初值,初值要设置成1,前提条件是dp[i]得等于1.因为只有长度为1的最长不降子序列的个数是唯一确定的,
    然后可以开始扫描了。
    这里要注意这个条件,着重着重着重!!!理解!!
    dp[j]+1==dp[i]
    为什么呢??
    注意题面,数字相同位置不同算不同,就是这个意思。
    好好理解
    然后就可以输出答案了,原理和上面的大同小异。
     
    代码:
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int n,ans,vis;
    int a[10001];
    int dp[10001];//表示以i结尾的最长不下降序列的长度。
    int len[10001];//表示以i为结尾的最长不降序列的个数.
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        for(int i=1;i<=n;i++)
        {
            dp[i]=1;
            for(int j=1;j<i;j++)
                if(a[j]<=a[i])
                    dp[i]=max(dp[j]+1,dp[i]);
        }
        vis=1;
        for(int i=1;i<=n;i++)
            if(dp[i]>dp[vis])
                vis=i;
        printf("%d
    ",dp[vis]);
        for(int i=1;i<=n;i++)
        {
            if(dp[i]==1)
                len[i]=1;
            else
                for(int j=1;j<i;j++)
                    if(a[j]<=a[i] && dp[j]+1==dp[i])
                        len[i]+=len[j];
        }
        for(int i=1;i<=n;i++)
            if(dp[i]==dp[vis])
                ans+=len[i];
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    学习笔记-Python基础4-九九乘法表练习
    学习笔记-Python基础4-函数
    学习笔记-Python基础3-程序结构:顺序、分支、循环
    JS根据获取的navigator.userAgent,判断用户打开页面的终端
    代理模式,CGLIB 与Spring AOP实现原理
    ueditor不过滤保存html
    ecstore 新增input控件方法
    ecstore前台模板保留css样式
    ecstore 当前网址
    mysql 导入数据过大报错
  • 原文地址:https://www.cnblogs.com/fusiwei/p/11236663.html
Copyright © 2011-2022 走看看