洛谷P1091 [NOIP 2004 提高组] 合唱队形 题解
本题做法
- 动态规划 DP。
思路
本题其实就是在求前序的最长递增子序列长度和后序的最长递增子序列长度在某个点 \(i\) 之和的最大值。由于本题的数据范围为 \(1\le n\le 100\),直接用 \(O(n^2)\) 的 DP 求最长递增子序列就行了。
代码
#include<bits/stdc++.h>
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
const int N=105;
int n,a[N],dp1[N],dp2[N],ans;
int main(){
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++) {
dp1[i]=1;
for(int j=1;j<i;j++) {
if(a[j]<a[i]) dp1[i]=max(dp1[i],dp1[j]+1);
}
}
for(int i=n;i>=1;i--) {
dp2[i]=1;
for(int j=n;j>i;j--) {
if(a[j]<a[i]) dp2[i]=max(dp2[i],dp2[j]+1);
}
}
for(int i=1;i<=n;i++) {
if(ans<dp1[i]+dp2[i]) ans=dp1[i]+dp2[i]-1;
}
cout<<n-ans<<endl;
return 0;
}