P1091 合唱队形 (DP&LIS)
思路:显然正反跑两边LIS,遍历一遍取最值即可。时间复杂度:O(n^2) 不过可以用upper_bound()压到O(nlogn)这里就不写这种做法了。。。。
AC代码:
#include<bits/stdc++.h>
using namespace std;
const int N=105;
int a[N],dp[2][N];//保存[1,n]和[n,1]的LIS
int main(){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
dp[0][1]=dp[1][n]=1;
for(int i=2,mx;i<=n;i++){ //正反跑两边LIS
mx=0;
for(int j=1;j<i;j++)
if(a[j]<a[i]&&dp[0][j]>mx)
mx=dp[0][j];
dp[0][i]=mx+1;
}
for(int i=n-1,mx;i>=1;i--){
mx=0;
for(int j=n;j>i;j--)
if(a[j]<a[i]&&dp[1][j]>mx)
mx=dp[1][j];
dp[1][i]=mx+1;
}
int ans=0;
for(int i=1;i<=n;i++)//遍历一遍取最值.
ans=max(ans,dp[0][i]+dp[1][i]-1);
printf("%d\n",n-ans);
return 0;
}