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

HDU1423 最长公共上升子序列

时间:2017-10-07 19:47:44      阅读:129      评论:0      收藏:0      [点我收藏+]

标签:stream   main   ==   mes   i++   ace   string   ring   return   

先离散化,然后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 最长公共上升子序列

标签:stream   main   ==   mes   i++   ace   string   ring   return   

原文地址:http://www.cnblogs.com/hua-dong/p/7635440.html

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