zoukankan      html  css  js  c++  java
  • 最长上升子序列问题

    问题描述
    有一个长为n的子序列A0,A1···An-1。求出这个序列中最长的上升子序列的长度。上升子序列指的是对于任意的i<j都满足Ai<Aj的子序列。

    我们定义dp[i],表示以Ai为末尾的最长上升子序列的长度

    以Ai结尾的上升子序列是:
    只包含Ai的子序列
    在满足j<i并且Aj<Ai的以Aj为结尾的上升子列末尾,追加上Ai后得到的子序列。

    #include<iostream>
    #include<stdio.h>
    using namespace std;
    int n;
    int a[1000];
    int dp[1000];
    void solve()
    {
        int ans=0;
        for(int i=0; i<n; i++)
        {
            dp[i]=1;
            for(int j=0; j<i; j++)
                if(a[j]<a[i])
                {
                    dp[i]=max(dp[i],dp[j]+1);
                }
            ans=max(ans,dp[i]);
        }
        printf("%d
    ",ans);
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=0; i<n; i++)
            scanf("%d",&a[i]);
        solve();
        return 0;
    }
    

    我们可以定义其他的递推关系
    dp[i],表示长度为i+1的上升子序列中末尾原始的最小值(不存在的话就是INF)。

    #include<iostream>
    #include<stdio.h>
    #define INF 0x3f3f3f3f
    using namespace std;
    int n;
    int a[1000];
    int dp[1000];
    void solve()
    {
        for(int i=0;i<n;i++)
            dp[i]=INF;
            for(int i=0;i<n;i++)
                *lower_bound(dp,dp+n,a[i])=a[i];
                ///函数lower_bound()在first和last中的前闭后开区间进行二分查找,返回大于或等于val的第一个元素位置。如果所有元素都小于val,则返回last的位置
            printf("%d
    ",lower_bound(dp,dp+n,INF)-dp);
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=0; i<n; i++)
            scanf("%d",&a[i]);
        solve();
        return 0;
    }
    
  • 相关阅读:
    Java 重写(Override)与重载(Overload)
    Java 继承
    Java 异常处理
    Java Scanner 类
    Java 流(Stream)、文件(File)和IO
    Java 方法
    Java 正则表达式
    Beta冲刺——代码规范、冲刺任务与计划
    Beta冲刺——凡事预则立
    Beta冲刺——问题总结博客(事后诸葛亮和组员交换事宜)
  • 原文地址:https://www.cnblogs.com/cmmdc/p/7196651.html
Copyright © 2011-2022 走看看