首先看到题目,乍一眼以为是LIS模板题,后来发现他是一个先递增后递减的序列。
那么可以把最大的那个数揪出来,然后左右划分,左边为一个正常的最长递增子序列,右边为一个倒过来的最长递增子序列。
然后只要序列中每个数为中心,然后取最大的一种情况就好了。
由于题目要求的是最少请几个人出去,那么就用总人数减去最大的合唱队列人数。
#include <bits/stdc++.h> using namespace std; int a[105]; int L[105]; inline int read() { int w = 0, f = 1; char ch = getchar(); while (ch < '0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); } while (ch >= '0' && ch <= '9') { w = (w << 3) + (w << 1) + ch - 48; ch = getchar(); } return w * f; } int main() { int n; n=read(); for(int i=1;i<=n;i++) a[i]=read(); int ans=0; for(int i=1;i<=n;i++) { int len1=0; int len2=0; memset(L,0,sizeof(L)); for(int j=1;j<i;j++) { if(a[j]>=a[i]) continue; if(a[j]>L[len1]) L[++len1]=a[j]; else { int p=lower_bound(L+1,L+1+len1,a[j])-L; L[p]=a[j]; } } memset(L,0,sizeof(L)); for(int j=n;j>i;j--) { if(a[j]>=a[i]) continue; if(a[j]>L[len2]) L[++len2]=a[j]; else { int p=lower_bound(L+1,L+1+len2,a[j])-L; L[p]=a[j]; } } ans=max(ans,len1+len2+1); } printf("%d\n",n-ans); }