• 算法练习题 2 合唱队


    题目

    题目描述

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

    合唱队形定义:设K位同学从左到右依次编号为1, 2, …, K,他们的身高分别为T1, T2, …, TK,

    则他们的身高满足T1 < T2 < … < Ti, Ti > Ti+1 > … > TK (1 <= i <= K)。
    要求:已知所有N位同学的身高,计算最少需要几位同学出列,可以使得剩下的同学排成合唱队形。

    输入

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

    输出

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

    解题思路

    首先将n个同学的身高存入a[n]中 ,当然数组大小需要大于该值 

    【解】假设队中最高的那个人的序列为 i ,那么他左边递增序列与右边递减序的和 列是所有人中最长的

    所以我们第一步需要找到每个同学左边递增序列的个数  

    例如有8位同学,身高分别为  186 186 150 200 160 130 197 200

    递增序列 inc[n] 的求法,每一个数只需要看每个数的序列值,设0<j<i<n , 若 a[j] < a[i] ,那么inc[i] = inc[j] + 1; 后面的数永远会添加之前出现的递增子串后,

    而且这里注意,我们最后得到inc[i] 应该是之前所有的inc[j]中最大那个+1

    186 186 150 200 160 130 197 200
    1 1 1 2 2 1 3 4

    递减序列 dec[n] 的求法和上面大同小异,如法炮制,只不过是从右往左找递增

    186 186 150 200 160 130 197 200
    3 3 2 3 2 1 1 1

    递增和递减序列都将自身算在内了,所以我们算总合唱团长度时需要减去自身的重复

    代码示意

    #include <iostream>
    #include <string>
    using namespace std;
    
    int main()
    {
        int N;
        int array[5000];
        while(cin>>N)
        {
            int i,j; 
            int inc[5000],dec[5000];//递增和递减序列
            for(i = 0;i<N;i++)
            {
                cin>>array[i];
                inc[i] = 1;
                dec[i] = 1;
            }
            if(N<=1) 
            {
                cout<<0<<endl;
                continue;
            }
            for(i = 0;i<N;i++)//求递增子串序列
            {
                for(j = 0;j<i;j++)
                {
                    if(array[i]>array[j]&&inc[j]+1>inc[i]) inc[i]=inc[j]+1;
                }
            }
            
            for(i = N-1;i>=0;i--)//求递减子串序列
            {
                for(j = N-1;j>i;j--)
                {
                    if(array[i]>array[j]&&dec[j]+1>dec[i]) dec[i] = dec[j]+1;
                }
            }
            int max = 0;
            for(i = 0;i<N;i++)
            {
                if(max < (inc[i]+dec[i]-1)) max = inc[i]+ dec[i]-1;//求最大合唱序列人数
            }
            cout<<N-max<<endl;
        }
        return 0;
    }
  • 相关阅读:
    Java接口总结
    java面向对象特点总结
    二分查找的两种实现方法
    关于Java的对象equals方法
    java加密枝术是怎样的?
    Java中子类和父类间的调用关系
    Java中字符串的完美度
    Java源代码不编译到字节码文件
    java生成6位随机数
    Struts2中ModelDriven的使用
  • 原文地址:https://www.cnblogs.com/Wen117/p/12688738.html
Copyright © 2020-2023  润新知