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 最长公共上升子序列的主要内容,如果未能解决你的问题,请参考以下文章