前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >每日一题C++版(合唱队)

每日一题C++版(合唱队)

作者头像
小白学视觉
发布2019-10-24 01:53:43
7020
发布2019-10-24 01:53:43
举报

编程是很多偏计算机、人工智能领域必须掌握的一项技能,此编程能力在学习和工作中起着重要的作用。因此小白决定开辟一个新的板块“每日一题”,通过每天一道编程题目来强化和锻炼自己的编程能力(最起码不会忘记编程)

特别说明:编程题来自“牛客网”和“领扣”以及热心小伙伴的题目。由于小白有时想锻炼某一类编程方法,所以提供的代码不一定是最优解,但是本文提供的编程代码均为通过测试代码。

合唱队

题目描述

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

说明:

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

输入描述:

整数N

输出描述:

最少需要几位同学出列

示例

输入

8

186 186 150 200160 130 197 200

输出

4

分析

首先计算每个数在最大递增子串中的位置(如何计算后文有讲解)

186 186 150 200 160 130 197 200 quene

1 1 1 2 2 1 3 4 递增计数

然后计算每个数在反向最大递减子串中的位置--->计算反向后每个数在最大递增子串中的位置

200 197 130 160 200 150 186 186 反向quene

1 1 1 2 3 2 3 3 递减计数

然后将每个数的递增计数和递减计数相加

186 186 150 200 160 130 197 200 quene

1 1 1 2 2 1 3 4 递增计数

3 3 2 3 2 1 1 1 递减计数

4 4 3 5 4 2 4 5 每个数在所在队列的人数+1(自己在递增和递减中被重复计算)

如160这个数

在递增队列中有2个人数

150 160

在递减队列中有2个人数

160 130

那么160所在队列中就有3个人

150 160 130

每个数的所在队列人数表达就是这个意思

总人数 - 该数所在队列人数 = 需要出队的人数

所以本题关键的问题就是如何找出最大的递增序列和递减序列。递减序列可以看作倒叙后的最大递增序列。因此,关键问题就是如何找到最大递增序列。小白采用的方法是首先将每一个数都遍历一次,首先将每个数都记为单独的递增序列,也就是位数为1,之后循环的过程中进行比较,如果后一个数比自己大,则比较后一个数的位数与当前位数+1的大小,如果当前数的位数+1大于后一个数的位数,则将后一个数的位数改为当前数的位数+1,否则不变。如果后面的数比当前数小,则用后一位数与第一层循环的数进行比较,采用同样的方式对位数进行更改。之后以后一位数变成当前数,再次进行比较,直到第一层遍历结束。

代码

代码语言:javascript
复制
#include <iostream>
#include <string>
#include <vector>
#include <sstream>

using namespace std;

class Solution
{
public:
  Solution(){}
  vector<int> GetOrder(vector<int> number, int n)
  {
    vector<int> order(n, 1);
    for (int i = 0; i < n; i++)
    {
      int m = number[i];
      int k = i;
      for (int j = i + 1; j < n; j++)
      {
        if (m < number[j] && order[k] >= order[j])
        {
          order[j] = order[k] + 1;
          m = number[j];
          k = j;
        }
        if (number[i]<number[j] && order[i] >= order[j])
        {
          order[j] = order[i] + 1;
          m = number[j];
          k = j;
        }
      }
    }
    return order;
  }
  int Maxorder(vector<int>Inorder, vector<int> Deorder)
  {
    int max;
    vector<int> sum;
    for (int i = 0; i < Inorder.size(); i++)
    {
      sum.push_back(Inorder[i] + Deorder[Inorder.size() - 1 - i]);
    }
    max = sum[0];
    for (int i = 1; i < Inorder.size(); i++)
    {
      if (max < sum[i])
      {
        max = sum[i];
      }
    }
    return max;
  }

private:

};

int main()
{
  int n;
  while(cin >> n)
    {
  vector<int> number;
  vector<int> denumber(n,0);
  Solution solution;
  vector<int> Inorder;
  vector<int> Deorder;
  
  for (int k = 0; k < n; k++)
  {
    int i;
    cin >> i;
    number.push_back(i);
  }
  for (int i = 0; i < n; i++)
  {
    denumber[i] = number[n-1-i];
  }
  Inorder = solution.GetOrder(number, n);
  Deorder = solution.GetOrder(denumber, n);
  int max = solution.Maxorder(Inorder, Deorder);
  cout << n - max + 1 << endl;
    }
  return 0;
}

运行结果

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-08-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 小白学视觉 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 合唱队
    • 题目描述
      • 分析
        • 代码
          • 运行结果
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档