动态规划(六)

合唱队形

题目描述

N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形。

合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2…,K,他们的身高分别为T1,T2,…,TK, 则他们的身高满足T1<...Ti+1>…>TK(1<=i<=K)。

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

输入输出格式

输入格式:

输入文件chorus.in的第一行是一个整数N(2<=N<=100),表示同学的总数。第一行有n个整数,用空格分隔,第i个整数Ti(130<=Ti<=230)是第i位同学的身高(厘米)。

输出格式:

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

输入输出样例

输入样例#1:
8
186 186 150 200 160 130 197 220
输出样例#1:
4



算法分析:由于本题的要求是中间高两边低,所以需要两次寻找最长上升子序列,即从1到n求一趟最长上升子序列,再从n到1求一趟最长上升子序列,最后枚举中间的Ti,然后从众多Ti种寻找个子最高的。

#include
using namespace std;
int n,ans,i,j,a[100001],f[2][200];
int main()
{
    cin>>n;
    for(i=1;i<=n;i++) cin>>a[i];
    a[0]=0;
    for(i=1;i<=n;i++)
    for(j=0;ja[j]) f[0][i]=max(f[0][i],f[0][j]+1);//从1到n求最长上升子序列
    a[n+1]=0;
    for(i=n;i>0;i--)
    for(j=n+1;j>i;j--)
    if(a[i]>a[j]) f[1][i]=max(f[1][i],f[1][j]+1);//从n到1求最长上升子序列
    for(i=1;i<=n;i++)
    ans=max(f[0][i]+f[1][i]-1,ans);//枚举Ti,从1到Ti的最长升+从TK到Ti的最长升-1(Ti被加了两次) 

    cout<

你可能感兴趣的:(动态规划(六))