【动态规划】合唱团

题目描述

N位同学站成一排,墨老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形。合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2,…,K,他们的身高分别为T1,T2,…,TK,  则他们的身高满足T1<T2<…<Ti>Ti+1>…>TK(1≤i≤K)。

你的任务是,已知所有N位同学的身高,计算最少需要几位同学出列,可以使得剩下的同学排成合唱队形。

 

输入

第一行是一个整数N(2≤N≤100),表示同学的总数。第一行有n个整数,用空格分隔,第i个整数Ti(130≤Ti≤230)是第i位同学的身高(厘米)。

 

输出

包括一行,这一行只包含一个整数,就是最少需要几位同学出列。

 

样例输入

8
186 186 150 200 160 130 197 220

样例输出

4

分析:最长递增子序列。。。

#include <iostream>
#include <string>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <deque>
#include <map>
#define range(i,a,b) for(int i=a;i<=b;++i)
#define LL long long
#define rerange(i,a,b) for(int i=a;i>=b;--i)
#define fill(arr,tmp) memset(arr,tmp,sizeof(arr))
using namespace std;
int n,a[105],dp[105],d[105],ans;
void init(){
    fill(dp,0);fill(d,0);
    cin>>n;
    range(i,0,n-1){
        cin>>a[i];
        dp[i]=d[i]=1;
    }
}
void solve(){
    range(i,1,n-1)range(j,0,i-1)if(a[i]>a[j])dp[i]=max(dp[i],dp[j]+1);
    rerange(i,n-1,0)rerange(j,n-1,i+1)if(a[i]>a[j])d[i]=max(d[i],d[j]+1);
    range(i,0,n){
        int mx1=0,mx2=0;
        range(j,0,i)mx1=max(mx1,dp[j]);
        range(j,i+1,n-1)mx2=max(mx2,d[i+1]);
        ans=max(ans,mx1+mx2);
    }
    cout<<n-ans<<endl;
}
int main() {
    init();
    solve();
    return 0;
}
View Code

 

posted @ 2018-07-21 14:00  RhythmLian  阅读(190)  评论(0编辑  收藏  举报