[華爲機試題]合唱隊

題目描述

計算最少出列多少位同學,使得剩下的同學排成合唱隊形

說明:

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;  
    }        
}



發佈了133 篇原創文章 · 獲贊 23 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章