题解 | 合唱队形
#include <bits/stdc++.h>
using namespace std;
const int SIZE=100000;
int dp[SIZE];
int dp2[SIZE];
int main(){
int n;
while(cin>>n){
memset(dp,INT_MIN,sizeof(dp));
int a[n];
for(int i=0;i<n;i++){
cin>>a[i];
}
for(int i=0;i<n;i++){
dp[i]=1;
for(int j=0;j<i;j++){
if(a[j]<a[i])dp[i]=max(dp[i],dp[j]+1);
}
}
for(int i=n-1;i>=0;i--){
dp2[i]=1;
for(int j=n-1;j>i;j--){
if(a[j]<a[i])dp2[i]=max(dp2[i],dp2[j]+1);
}
}
int ans=1;
for(int i=0;i<n;i++){
if(dp[i]+dp2[i]>ans)ans=dp[i]+dp2[i];
}
cout<<n-ans+1<<endl;
}
}
本题要找到两个方向上的最长段,可以知道,他要一个尖角,那么其实并不困难,只需要找到在 i 点往前和往后的最优删除即可,就利用我们的最优长度的计算方法,去找到两个最值,根据数学分析,可以知道n+1-两个的和,就是我们要的结果

查看4道真题和解析