题意:求最长公共上升子序列的长度
注意:题目中没有提及,每组输出之间要空一行,最后一次输出不需要空行。
思路:dp[i][j]表示A序列的前i个数和B序列的前j个数的最长公共上升子序列的长度。temp[i][j]表示A序列的前i个数和B序列的前j个数的最长公共上升子序列的最后一个数字(如果长度相同的,取最后一个数字最小的)
#include <iostream>
#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <iomanip>
#include <cstdlib>
#include <string.h>
#include <vector>
#include <queue>
#include <stack>
#include <ctype.h>
using namespace std;
typedef long long ll;
ll a[505],b[505];
int dp[505][505];
ll temp[505][505];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(dp,0,sizeof(dp));
memset(temp,0x7f7f7f,sizeof(temp));
temp[0][0]=-temp[0][0];
int n,m;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
temp[i][0]=-temp[i][0];
}
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
scanf("%lld",&b[i]);
temp[0][i]=-temp[0][i];
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(a[i]==b[j])
{
if(a[i]>temp[i-1][j-1])
{
dp[i][j]=dp[i-1][j-1]+1;
temp[i][j]=a[i];
}
else
{
dp[i][j]=dp[i-1][j-1];
temp[i][j]=temp[i-1][j-1];
}
}
else
{
if(dp[i-1][j]>dp[i][j-1])
{
dp[i][j]=dp[i-1][j];
temp[i][j]=temp[i-1][j];
}
else if(dp[i][j-1]>dp[i-1][j])
{
dp[i][j]=dp[i][j-1];
temp[i][j]=temp[i][j-1];
}
else
{
dp[i][j]=dp[i][j-1];
temp[i][j]=min(temp[i][j-1],temp[i-1][j]);
}
}
}
}
cout<<dp[n][m]<<endl;
if(t!=0) cout<<endl;
}
return 0;
}