假设城市中一共有N幢建筑排成一条线,每幢建筑的高度各不相同。初始时,怪盗基德可以在任何一幢建筑的顶端。他可以选择一个方向逃跑,但是不能中途改变方向(因为中森警部会在后面追击)。因为滑翔翼动力装置受损,他只能往下滑行(即:只能从较高的建筑滑翔到较低的建筑)。他希望尽可能多地经过不同建筑的顶部,这样可以减缓下降时的冲击力,减少受伤的可能性。请问,他最多可以经过多少幢不同建筑的顶部(包含初始时的建筑)?
本题无非还是求最大上升子序列的问题,只不过记得可以在任意一座房上选两方向任意,该题便是将该数列正着求一遍最大上升子序列求出最大值在反着求一遍的另一个最大值,两值比较求最大。
#include<iostream>
#include<string.h>
using namespace std;
int main()
{
long long a[101]={0},b[101]={0},s=0,max=0,m,n;
cin>>n;
while(n--)
{
cin>>m;
for(int i=1;i<=m;i++)
{cin>>a[i];}
b[1]=1;
for(int i=2;i<=m;i++)
{
for(int j=1;j<i;j++)
{
if(a[j]>a[i])
{if(b[j]>max){max=b[j];}}
}
b[i]=max+1;max=0;
}
max=0;
for(int i=1;i<=m;i++)
{if(b[i]>max){max=b[i];}}
s=max;
max=0;memset(b,0,sizeof(b));b[m]=1;
for(int i=(m-1);i>=1;i--)
{
for(int j=m;j>i;j--)
{
if(a[j]>a[i])
{if(b[j]>max){max=b[j];}}
}
b[i]=max+1;max=0;
}
max=0;
for(int i=1;i<=m;i++)
{if(b[i]>max){max=b[i];}}
if(s>max){cout<<s<<endl;}
else{cout<<max<<endl;}
memset(b,0,sizeof(b));s=0;max=0;
}
}