最长“山顶”子序列
DP:分别递推以s[i]开头的最长下降子序列、以s[i]结尾的最长上升子序列
#include<iostream>
#include<cstring>
using namespace std;
const int maxn=101;
int s[maxn];
int high[maxn];//上升子序列长度
int low[maxn];//下降子序列长度
int student(int n){//“山顶”子序列最大长度
fill(high,high+n,1);
fill(low,low+n,1);
for(int i=0;i<n;i++){//从前往后:统计以s[i]结尾的最长上升子序列
for(int j=0;j<i;j++){
if(s[i]>s[j])high[i]=max(high[i],high[j]+1);
}
}
for(int i=n-1;i>=0;i--){//从后往前:统计以s[i]开头的最长下降子序列
for(int j=n-1;j>i;j--){
if(s[i]>s[j])low[i]=max(low[i],low[j]+1);
}
}
int ans=0;
for(int i=0;i<n;i++){
ans=max(ans,high[i]+low[i]-1);
}
return ans;
}
int main(){
int n;
while(scanf("%d",&n)!=EOF){
for(int i=0;i<n;i++){
scanf("%d",&s[i]);
}
printf("%d\n",n-student(n));
}
return 0;
}