題目描述
計算最少出列多少位同學,使得剩下的同學排成合唱隊形
說明:
N位同學站成一排,音樂老師要請其中的(N-K)位同學出列,使得剩下的K位同學排成合唱隊形。
合唱隊形是指這樣的一種隊形:設K位同學從左到右依次編號爲1,2…,K,他們的身高分別爲T1,T2,…,TK, 則他們的身高滿足存在i(1<=i<=K)使得T1<T2<......<Ti-1<Ti>Ti+1>......>TK。
你的任務是,已知所有N位同學的身高,計算最少需要幾位同學出列,可以使得剩下的同學排成合唱隊形。
輸入描述:
整數N
輸出描述:
最少需要幾位同學出列
輸入例子:
8 186 186 150 200 160 130 197 200
輸出例子:
4思路:用最長遞增子序列的方法,複雜度是O(n2),求出每個同學爲中心的,左邊最長遞增子序列和右邊的最長遞減子序列,然後計算此時最少出列的同學數,最後求每個同學爲中心的情況的最小值。
求遞增子序列用動態規劃的方法,令f(i)表示以i結尾的最長遞增子序列的長度,f(i)=max{f(j)+1},j<i並且num[j]<num[i](也就是i前面所有元素結尾時的最長遞增子序列的最大值)
#include<iostream>
#include<vector>
using namespace std;
int main(){
int N;
while(cin>>N){
vector<int> height(N,0);
vector<int> left(N,1);
vector<int> right(N,1);
for(int i=0;i<N;++i)
cin>>height[i];
for(int i=1;i<N;++i){
int maxIncLen=0;
for(int j=0;j<i;++j){
if(height[j]<height[i]&&left[j]+1>left[i])
left[i]=left[j]+1;
}
}
for(int i=N-2;i>=0;--i){
for(int j=N-1;j>i;--j){
if(height[j]<height[i]&&right[j]+1>right[i])
right[i]=right[j]+1;
}
}
int maxLen=0;
for(int i=0;i<N;++i){
if(left[i]+right[i]-1>maxLen)
maxLen=left[i]+right[i]-1;
}
cout<<N-maxLen<<endl;
}
}