合唱队型

题目描述

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

思路:看完题目,我们知道,这,又是道动规题。假设第i(0<= i <= n - 1)个同学为最高点,分别求出此时i左边的最长递增子序列长度inc1[i],i右边的最长递减子序列长度inc2[i],由于最高点i同时包括在了inc1[i]和inc2[i]之中,因此实际的合唱队形的长度为inc1[i] + inc2[i] - 1。而我们求得的最后结果就是i从1到n - 1中,使得inc1[i] + inc2[i] - 1最大的情况。

代码:

#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
int n,a[1000],f[1000][1000],z;
void emm()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++) 
    scanf("%d",&a[i]);//读数。
    a[0]=0;
    for(int i=1;i<=n;i++)
    for(int j=0;j<i;j++) 
    if(a[i]>a[j])
     f[0][i]=max(f[0][i],f[0][j]+1);
    a[n+1]=0;
}
void emmm()
{
for(int i=n;i;i--)
    for(int j=n+1;j>i;j--) 
    if(a[i]>a[j]) 
    f[1][i]=max(f[1][i],f[1][j]+1);//动态转移方程。
    for(int i=1;i<=n;i++) z=max(f[0][i]+f[1][i]-1,z);
    printf("%d\n",n-z);//输出。
}    
  int main()
  {
      emm();//调用emm函数。
      emmm();//调用emmm函数。
    return 0;

}  
真香!!!    

猜你喜欢

转载自blog.csdn.net/hunkwu/article/details/82955725