题目大意是找第二长不降子序列,如果两个序列数字一样但是数字在原序列下标不一样也算不同序列。
答案无非两种可能 1.等于最长序列长度 2.最长序列长度-1
情况分析:
1.第一次到达最长序列长度,再往后扫描,如果再次出现最长序列长度的,那么答案就是最长序列长度
2.第一次出现最长序列的位置往前扫描,如果序列之间出现重复数字(如1 2 2 5)或者(1 4 3 5)情况,答案就是最长序列长度
3.其余便是最长序列长度-1
代码:
#include<stdio.h>
#include<string.h>
int a[1001],dp[1001],p[1001];
int main()
{
int T;
int i,j,n;
int max,secondmax,t,flag,temp,num;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
memset(a,0,sizeof(a));
memset(dp,0,sizeof(dp));
memset(p,0,sizeof(p));
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
p[i]=i;
}
max=0;
for(i=0;i<n;i++)
{
dp[i]=1;
for(j=0;j<i;j++)
{
if(a[i]>a[j] && dp[i]<dp[j]+1)
{
dp[i]=dp[j]+1;
p[i]=j; //记录序列的第一个前驱
}
}
if(max<dp[i])
{
max=dp[i];
num=i;
}
}
flag=0;
temp=max;
for(i=n-1;i>num;i--)
{
if(dp[i]==max)
{
flag=1;
break;
}
}
i=num;
while(flag!=1 && temp>0)
{
t=p[i];
for(j=i-1;j>t;j--)
{
if(a[j]==a[t])//1 2 2 5 5 中间夹相同数的
{
flag=1;
break;
}
else if(a[j]<a[i] && dp[j]==dp[t]) //1 4 3 5
{
flag=1;
break;
}
}
temp--;
i=j;
}
if(flag==1)
secondmax=max;
else
secondmax=max-1;
printf("%d\n",secondmax);
}
return 0;
}