题目大意:给定一个序列,求解出这样的序列,使得这个序列在原序列中相对位置不变,从a[0]到a[middle]上升,从a[middle]到a[n]下降,且关于中间元素对称的最长的序列,输出最长的长度。
这题一开始没想太懂,后来看了别人的算法,突然明白过来原来是求解最长公共上升子序列。为什么呐?
因为这里要求解对称的先上升后下降的序列,试想将序列倒置后与原序列求解最长公共上升子序列就行了。对于最长公共上升子序列,就是在最长公共子序列的基础上增加判断是否上升即可。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#define maxn 206
#define max(a,b) a>b?a:b
using namespace std;
int a[maxn];
int dp[maxn]; //dp[i]代表以i结尾的序列的最长公共上升子序列
int main()
{
int Tcas;
scanf("%d",&Tcas);
while(Tcas--)
{
int n;
scanf("%d",&n);
for(int i=0;i<n;i++) scanf("%d",&a[i]);
memset(dp,0,sizeof(dp));
int ans = 0;
//一维数组的写法
for(int i=n-1;i>=0;i--)
{
int len = 0;
for(int j=0;j<=i;j++)
{
if(a[j] < a[i])
len = max(len,dp[j]);
else if(a[j]==a[i])
dp[j] = len + 1;
if(j<i && ans<2*dp[j])
ans = 2 * dp[j];
else
ans = max(ans,dp[j]*2-1);
}
}
printf("%d\n",ans);
}
system("pause");
return 0;
}