码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2018-01-20 11:10:39      阅读:167      评论:0      收藏:0      [点我收藏+]

标签:esc   ons   log   inpu   panel   strong   最长上升子序列   nbsp   scanf   

传送门

题目描述 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)做法

 

 

 

 

 

 

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

标签:esc   ons   log   inpu   panel   strong   最长上升子序列   nbsp   scanf   

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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!