【ACM】华为oj--合唱队

 
  

题目描述:

计算最少出列多少位同学,使得剩下的同学排成合唱队形

说明:

N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形。 
合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2…,K,他们的身高分别为T1,T2,…,TK,   则他们的身高满足存在i(1<=i<=K)使得TiTi+1>......>TK。 
     你的任务是,已知所有N位同学的身高,计算最少需要几位同学出列,可以使得剩下的同学排成合唱队形。

输入:

整数N

一行整数,空格隔开,N位同学身高

输出:

最少需要几位同学出列

样例:

8 186 186 150 200 160 130 197 200

4

分析: 动态规划基础题。对每个身高求以它为终点的最长升子序列,以它为起点的最长降子序列,就可以求出需要出列的最少人数。实现的时候我是正序求一遍最长升子序列,再逆序求一遍最长升子序列。至于求最长子序列,简单解释一下:

将求以ak为终点的最长升子序列转化为:

MaxLen (k) = Max { MaxLen (i):1

意思就是就是找出在ak左边,“终点”数值小于ak,且长度最大的那个上升子序列的长度再加1,就是ak的最长升子序列了。

#include 
#include 
#include 
#include 

#define MAX_N 1000

using namespace std;

int FindLeast(int arr[],int n)
{
    int lissqe[MAX_N][2],i,j,minlen=n,maxlen;
    lissqe[0][0]=1;
    lissqe[n-1][1]=1;
    for(i=1;i=0;j--)
        {
            if(arr[j]maxlen)
            {
                maxlen=lissqe[j][0];
            }

        }
        lissqe[i][0]=maxlen+1;
    }
    for(i=n-2;i>=0;i--)
    {
        maxlen=0;
        for(j=i+1;jmaxlen)
            {
                maxlen=lissqe[j][1];
            }

        }
        lissqe[i][1]=maxlen+1;
    }
    for(i=0;i>N;
    for(int i=0;i>sing[i];
    }
    cout<


你可能感兴趣的:(ACM)