Codevs 2188 最长上升子序列 - 序列DP

传送门

题目描述 Description

LIS问题是最经典的动态规划基础问题之一。如果要求一个满足一定条件的最长上升子序列,你还能解决吗?

给出一个长度为N整数序列,请求出它的包含第K个元素的最长上升子序列。

例如:对于长度为6的序列<2,7,3,4,8,5>,它的最长上升子序列为<2,3,4,5>,但如果限制一定要包含第2个元素,那么满足此要求的最长上升子序列就只能是<2,7,8>了。

输入描述 Input Description

第一行为两个整数N,K,如上所述。

接下来是N个整数,描述一个序列。

输出描述 Output Description

请输出两个整数,即包含第K个元素的最长上升子序列长度。

样例输入 Sample Input

8 6

65 158 170 299 300 155 207 389

样例输出 Sample Output

4

数据范围及提示 Data Size & Hint

80%的数据,满足0<n<=1000,0<k<=n

100%的数据,满足0<n<=200000,0<k<=n

思路:

本题要求包含第K个元素的最长上升子序列长度,因此最长上升子序列长度dp[n]必须由dp[k]转移来。

AC Code:

80分 O(n^2)做法

#include<cstdio>
#include<algorithm>
using namespace std;
const int sz=200000+10;
int a[sz];
int dp[sz];
int main()
{
    int n,k;
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    int ans=-99;
    for(int i=1;i<=n;i++)
    {
        dp[i]=1;
        for(int j=1;j<i;j++)
        {
            if(a[j]<a[i])
            {
                if(j<k&&a[j]<a[k])
                    dp[i]=max(dp[i],dp[j]+1);
                else if(j==k)
                    dp[i]+=1;
                else if(j>k&&a[j]>a[k])
                    dp[i]=max(dp[i],dp[j]+1);
            }
        }
        ans=max(ans,dp[i]);
    }
    printf("%d",ans);
    return 0;
}

100分 O(nlogn)做法

原文地址:https://www.cnblogs.com/Loi-Brilliant/p/8319809.html

时间: 2024-10-27 18:21:27

Codevs 2188 最长上升子序列 - 序列DP的相关文章

codevs 2188 最长上升子序列

题目描述 Description LIS问题是最经典的动态规划基础问题之一.如果要求一个满足一定条件的最长上升子序列,你还能解决吗? 给出一个长度为N整数序列,请求出它的包含第K个元素的最长上升子序列. 例如:对于长度为6的序列<2,7,3,4,8,5>,它的最长上升子序列为<2,3,4,5>,但如果限制一定要包含第2个元素,那么满足此要求的最长上升子序列就只能是<2,7,8>了. 输入描述 Input Description 第一行为两个整数N,K,如上所述. 接下来

最长上升子序列--经典dp

最长上升子序列 Time Limit: 3000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 一个数的序列bi,当b1 < b2 < ... < bS的时候,我们称这个序列是上升的.对于给定的一个序列(a1, a2, ..., aN),我们可以得到一些上升的子序列(ai1, ai2, ..., aiK),这里1<= i1 < i2 < ... < iK <= N.比如,对于序列(1, 7, 3, 5, 9, 4, 8)

LCS 最长公共子序列(DP经典问题)

最长公共子序列问题以及背包问题都是DP(动态规划)算法的经典题目,值得深度挖掘以致了解DP算法思想.问题如下: 最长公共子序列 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描述 咱们就不拐弯抹角了,如题,需要你做的就是写一个程序,得出最长公共子序列. tip:最长公共子序列也称作最长公共子串(不要求连续),英文缩写为LCS(Longest Common Subsequence).其定义是,一个序列 S ,如果分别是两个或多个已知序列的子序列,且是所有符合此条件序列中最

poj2533——lis(最长上升子序列), 线性dp

poj2533——lis(最长上升子序列), 线性dp Longest Ordered Subsequence Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 36143   Accepted: 15876 Description A numeric sequence of ai is ordered if a1 < a2 < ... < aN. Let the subsequence of the given n

nyoj 36 最长公共子序列 【DP】

今天听了老师讲的最长公共子序列,就拿以前做过的题又做了一遍... 我用的是最简单普通的方法, 代码: #include<stdio.h> #include<string.h> #include<algorithm> using namespace std; int dp[1005][1005]; int main() { char a[1005], b[1005]; int t; scanf("%d", &t); while(t --){ s

nyoj36最长公共子序列(dp)

最长公共子序列 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描述 咱们就不拐弯抹角了,如题,需要你做的就是写一个程序,得出最长公共子序列.tip:最长公共子序列也称作最长公共子串(不要求连续),英文缩写为LCS(Longest Common Subsequence).其定义是,一个序列 S ,如果分别是两个或多个已知序列的子序列,且是所有符合此条件序列中最长的,则 S 称为已知序列的最长公共子序列. 输入 第一行给出一个整数N(0<N<100)表示待测数据组数接下来

LCS(最长公共子序列)和dp(动态规划)

参照:v_JULY_v 最长公共子序列定义: 注意最长公共子串(Longest CommonSubstring)和最长公共子序列(LongestCommon Subsequence, LCS)的区别:子串(Substring)是串的一个连续的部分,子序列(Subsequence)则是从不改变序列的顺序,而从序列中去掉任意的元素而获得的新序列:更简略地说,前者(子串)的字符的位置必须连续,后者(子序列LCS)则不必.比如字符串acdfg同akdfc的最长公共子串为df,而他们的最长公共子序列是ad

最长上升子序列(dp)

链接:https://www.nowcoder.com/questionTerminal/d83721575bd4418eae76c916483493de来源:牛客网 广场上站着一支队伍,她们是来自全国各地的扭秧歌代表队,现在有她们的身高数据,请你帮忙找出身高依次递增的子序列. 例如队伍的身高数据是(1.7.3.5.9.4.8),其中依次递增的子序列有(1.7),(1.3.5.9),(1.3.4.8)等,其中最长的长度为4. 输入描述: 输入包含多组数据,每组数据第一行包含一个正整数n(1≤n≤

BZOJ 3173: [Tjoi2013]最长上升子序列 [splay DP]

3173: [Tjoi2013]最长上升子序列 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1613  Solved: 839[Submit][Status][Discuss] Description 给定一个序列,初始为空.现在我们将1到N的数字插入到序列中,每次将一个数字插入到一个特定的位置.每插入一个数字,我们都想知道此时最长上升子序列长度是多少? Input 第一行一个整数N,表示我们要将1到N插入序列中,接下是N个数字,第k个数字Xk