题解 | 合唱队形
#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-两个的和,就是我们要的结果