题目链接
题目大意
用 N 个建筑排成一条线,高度不尽相同,怪盗基德可以任意选择一个楼作为起点,向左或者向右飞行,但是每一次的落点都必须比上一次的楼层低,求怪盗基德最多可以落多少个建筑物。
题意解析
第一种情况:当怪盗基德只往左飞的时候,如果以任意一栋楼 i 作为起点,那么就可以看成以 i 为端点的最长上升子序列
第二种情况:当怪盗基德只往右飞的时候,如果以任意一栋楼 i 作为起点,那么就可以看成以 i 为端点的最长下降子序列,也就是从右往左的最长上升子序列
因此这个题目的解题思路就是分别从左往右和从右往左求一遍最长上升子序列,然后求最大值即可。
那么接下来看一看最长上升子序列,最长上升子序列经典例题:300. 最长递增子序列
最长上升子序列
- 状态表示:dp[i] 表示从第一个数开始,以 第 i 个数结尾的上升子序列 ,属性为(Max)
- 状态计算:当 dp[j]<dp[i]的时候 : dp[i]=max(dp[i],dp[j]+1) (j<i),dp[i] 初始值为 1
代码
#include<iostream>
using namespace std;
const int N=110;
int a[N];
int dp[N];
int main()
{
int t; cin>>t;
while(t--)
{
int n; cin>>n;
int ans=0;
for(int i=1;i<=n;i++) cin>>a[i];
//最长上升子序列
for(int i=1;i<=n;i++)
{
dp[i]=1;
for(int j=1;j<i;j++)
{
if(a[i]>a[j]) dp[i]=max(dp[i],dp[j]+1);
}
ans=max(ans,dp[i]);
}
//最长下降子序列,就是上升子序列反过来
for(int i=n;i;i--)
{
dp[i]=1;
for(int j=n;j>i;j--)
{
if(a[i]>a[j]) dp[i]=max(dp[i],dp[j]+1);
}
ans=max(ans,dp[i]);
}
cout<<ans<<endl;
}
return 0;
}
1591

被折叠的 条评论
为什么被折叠?



