明显把这题想简单了。。。。WA了好多次,后来题解中提到LCIS。。。才知道咋回事,弱成虫。。。。。。。
LCIS,即最大单调上手公共子序列
令dp[i][j]表示为s1串前i项,s2串前j项,并以b[j]为结尾的最大单调公共子序列
则当a[i]!=b[j]时,dp[i][j]=dp[i-1][j]
反之,dp[i][j]=max{dp[i][j],dp[i-1][k]},b[k]<b[j]且0<k<j
本题的第二个序列即将原序列自反即可,最后处理略麻烦,小心一下,附代码:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <cmath>
#define N 300
#define cl(a) memset(a,0,sizeof(a))
using namespace std;
int a[N],b[N],f[N][N];
int main()
{
int T,n,i,j,k,res,zmax;
cin>>T;
while (T--)
{
cin>>n;
for (i=1;i<=n;i++)
{
cin>>a[i];
b[n+1-i]=a[i];
}
cl(f);
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
if (a[i]!=b[j]) f[i][j]=f[i-1][j];
else
{
f[i][j]=1;
for (k=1;k<j;k++)
if (b[k]<b[j]) f[i][j]=max(f[i][j],f[i-1][k]+1);
}
res=1;
for (i=1;i<=n;i++)
{
zmax=-1;
for (j=n-i;j>=1;j--)
{
if (zmax>b[j]) res=max(f[i][j]*2+1,res);
else res=max(res,f[i][j]*2);
zmax=max(zmax,b[j]);
}
}
cout<<res<<endl;
}
return 0;
}