HDU5489 Removed Interval(动态规划)

一个长度为n的序列,删除任意长度为l的连续子序列后,求剩下的序列的最长公共子序列。

 

先求出以第i个元素为开始的LIS的长度,再一次循环,对所要求的结果更新

 

#include<iostream>
#include<cstdio>
#include< string>
#include<cstring>
#include<cstdlib>
#include<queue>
#include<vector>
#include<algorithm>
const  int INF =  0x3F3F3F3F;
using  namespace std;
typedef  long  long LL;
const  int N =  200008;
int a[N];
int lis[N], dp[N];

int main(){
     int n, l;
     int t;
    cin>>t;
     for( int t1 =  1; t1 <= t; t1++){
        scanf( " %d %d ",&n, &l);
         for( int i =  0; i < n; i++){
            scanf( " %d ", &a[i]);
        }
        a[n] = INF;
         int pos =  0 , len =  1;
        lis[n] =  0;
        lis[n -  1] =  1;
        dp[ 0] = -a[n -  1];
         for( int i = n -  2; i >=  0; i--){
            pos = lower_bound(dp, dp + len, -a[i]) - dp;
            dp[pos] = -a[i];
             if(pos == len){
                len++;
            }
            lis[i] = pos +  1;
        }
         int ans = lis[l];
        len =  1;
        dp[ 0] = a[ 0];
         for( int i =  1, j = l; j < n; i++, j++){
             int tp = lis[j +  1];
            pos = lower_bound(dp, dp + len, a[j +  1]) - dp;
            tp += pos;
            ans = max(ans, tp);

            pos = lower_bound(dp, dp + len, a[i]) - dp;
            dp[pos] = a[i];
             if(pos == len){
                len++;
            }
    }


    printf( " Case #%d: %d\n ", t1, ans);
    }
     return  0;

} 

转载于:https://www.cnblogs.com/IMGavin/p/5708936.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值