1996:登山
传送门
1、此题坑点在于先上山后要下山
2、最后求上升子序列+下降子序列的最长长度类似 1481:Maximum sum这题
3、要注意的是
写双重循环时内重循环 j++ 不要 写成外层循环变量 i++
这种错误在写这题出现了两次,陷入死循环不得出来
在此题中用这样 求下降子序列长度的方式 行不通,因为最终求的是
从左到右的最长上升子序列+接着的最长下降子序列,
如果这种循环方式确实能求出最长下降子序列,但是dp1[i]表示的就是从下标0到i这一段的最长下降子序列
而按题意要求的应该是
从下标i到n-1这一段的最长下降子序列
下面这个例子就过不去,正确8,这种错误得出7
15
42 194 223 321 2 54 59 8 54 4 3 6 37 97 54 32
for(int i=0;i<n;i++){
for(int j=0;j<i;j++){
if(a[j]>a[i]){
dp1[i]=max(dp1[j]+1,dp1[i]);
}
}
}
求下降子序列这两种皆可
for(int i=n-2;i>=0;i--){
for(int j=n-1;j>i;j--){
if(a[j]<a[i]){
dp1[i]=max(dp1[j]+1,dp1[i]);
}
}
}
// for(int i=n-1;i>=0;i--){
// for(int j=i+1;j<n;j++){
// if(a[j]<a[i]){
// dp1[i]=max(dp1[j]+1,dp1[i]);
// }
// }
// }
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
cin>>n;
int a[n];
int dp[n];//dp[i]代表以a[i]结尾的数段(从右开始)下降序列的长度
//相当于从左开始求上升序列(比较符合我习惯 ,,好叭,难以逃开从右开始
// memset(dp,1,sizeof(dp));
// dp[0]=1;
int dp1[n];
for(int i=0;i<n;i++){
cin>>a[i];
dp[i]=1;
dp1[i]=1;
}
for(int i=1;i<n;i++){
for(int j=0;j<i;j++){
if(a[j]<a[i]){
dp[i]=max(dp[j]+1,dp[i]);
//前边i个数都有对应的上升序列,找出最大的上升数+1
}
}
}
for(int i=n-2;i>=0;i--){
for(int j=n-1;j>i;j--){
if(a[j]<a[i]){
dp1[i]=max(dp1[j]+1,dp1[i]);
}
}
}
// for(int i=n-1;i>=0;i--){
// for(int j=i+1;j<n;j++){
// if(a[j]<a[i]){
// dp1[i]=max(dp1[j]+1,dp1[i]);
// }
// }
// }
int res=0;
// int res=dp[0]+dp1[0]-1;
//上升子序列的终点是i,下降子序列的起点是i,i这个点算了两次
for(int i=0;i<n;i++){
res=max(res,dp[i]+dp1[i]-1);
}
cout<<res<<endl;
// cout<<*max_element(dp,dp+n)<<endl;
return 0;
}