HDU1423 最长公共上升子序列

Posted ---学习ing---

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU1423 最长公共上升子序列相关的知识,希望对你有一定的参考价值。

先离散化,然后DP

注意这个解法中,dp[i][j][k]代表a序列中前i个和b序列中前j个数结尾为k或小于k时的最大。

但是由于i是单增(一次1->n),而j反复变化(多次1->m),因此i可以滚动,而j不可以

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
using namespace std;
int x[501],y[501],xx[501],yy[501],dp[2][501][1001];
int tmp[1002],cnt,m,n,Max;
map<int,int>q;
void _lisan()
{
        int i,j;
        q.clear();
        cnt=0;
        scanf("%d",&n);
        for(i=1;i<=n;i++) {
            scanf("%d",&x[i]);
            tmp[i]=x[i];
        }
        scanf("%d",&m);
        for(i=1;i<=m;i++) {
            scanf("%d",&y[i]);
            tmp[n+i]=y[i];
        }
        sort(tmp+1,tmp+m+n+1);
        q[tmp[1]]=++cnt;
        for(i=2;i<=m+n;i++)
         if(tmp[i]!=tmp[i-1]) q[tmp[i]]=++cnt;
        for(i=1;i<=n;i++)xx[i]=q[x[i]];
        for(i=1;i<=m;i++)yy[i]=q[y[i]];
        memset(dp,0,sizeof(dp));
        Max=0;
}
int main()
{
    int T,i,j,k;
    cin>>T;
    while(T--){
        _lisan();
        for(i=1;i<=n;i++)
         for(j=1;j<=m;j++)
         {
            if(xx[i]==yy[j]){
              dp[i%2][j][xx[i]]=max(dp[i%2][j][xx[i]],dp[(i+1)%2][j-1][xx[i]-1]+1);
            }
            for(k=0;k<=cnt;k++)
           {
             dp[i%2][j][k]=max(dp[i%2][j][k],dp[(i+1)%2][j][k]);
             dp[i%2][j][k]=max(dp[i%2][j][k],dp[i%2][j][k-1]);
             dp[i%2][j][k]=max(dp[i%2][j][k],dp[i%2][j-1][k]);    
           }       
        } 
        printf("%d\n",dp[n%2][m][cnt]);
        if(T)printf("\n");
    }
    return 0;
}

 

以上是关于HDU1423 最长公共上升子序列的主要内容,如果未能解决你的问题,请参考以下文章

HDU-1423 最长公共上升子序列(LCIS)

HDU-1423-Greatest Common Increasing Subsequence-最长公共上升子序列模版

hdu4604 Deque(最长上升子序列变形)

刷题之最长公共/上升子序列问题

acwing 272. 最长公共上升子序列

LIS LCS 最长上升子序列 最长公共子序列 ...