做题感悟:这题在学习了LCIS后才做的,正好用于练手。
解题思路:依次枚举每个点,分成两段,得记录一下最长的最大值是否比最后一个元素小。
代码:
#include<stdio.h>
#include<iostream>
#include<map>
#include<string>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std ;
const int INF = 99999999 ;
const int MX = 505 ;
int n ;
int a[MX],b[MX],f[MX] ;
int max(int x,int y)
{
return x > y ? x : y ;
}
int LCIS()
{
int best=0 ;
for(int k=1 ;k<n-1 ;k++)
{
int ans=0,temp=-1 ;
memset(f,0,sizeof(f)) ;
for(int i=0 ;i<k ;i++)
for(int p=400,j=0 ;j<n-k ;j++)
{
if(a[i]==b[j]&&f[p]+1>f[j])
f[j]=f[p]+1 ;
if(a[i]>b[j]&&f[p]<f[j])
p=j ;
if(ans<f[j])
{
temp=b[j] ; // 记录最长的最大值
ans=f[j] ;
}
}
if(temp!=-1&&(a[k-1]>temp||b[n-k-1]>temp)) // 判断最右边的值是否可以单独加上
best=max(best,ans*2+1) ;
else best=max(best,ans*2) ;
}
return best ;
}
int main()
{
int T ;
scanf("%d",&T) ;
while(T--)
{
scanf("%d",&n) ;
for(int i=0 ;i<n ;i++)
{
scanf("%d",&a[i]) ;
b[n-i-1]=a[i] ;
}
printf("%d\n",LCIS()) ;
}
return 0 ;
}
优代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=220;
int n,a[N],b[N],dp[N];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
b[n+1-i]=a[i];
}
memset(dp,0,sizeof(dp));
int len,ans=1;
for(int i=1;i<=n;i++)
{
len=0;
for(int j=1;j<=(n-i+1);j++)
{ //j<=n-i+1 保证最多中间只重复一人
if(a[i]>b[j])
len=max(len,dp[j]);
else if(a[i]==b[j])
dp[j]=max(dp[j],len+1);
if(i<(n+1-j)) //判断是否重叠
ans=max(ans,dp[j]*2);
else
ans=max(ans,dp[j]*2-1);
}
}
printf("%d\n",ans);
}
return 0;
}