合唱队问题

来源:互联网 发布:微博mac客户端是什么 编辑:程序博客网 时间:2024/06/07 23:03

题目描述

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

输入描述:
整数N

输出描述:
最少需要几位同学出列

输入例子:
8
186 186 150 200 160 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

每个数的所在队列人数表达就是这个意思
总人数 - 该数所在队列人数 = 需要出队的人数

#include <iostream>#include <vector>#include <algorithm>using namespace std;void calIncSub(vector<int> quene, vector<int> &Num){    for(int i=1;i<quene.size();i++)        for(int j=i-1;j>=0;j--)            if(quene[j]<quene[i] && Num[i]<Num[j]+1)  //找到前面比当前小的,且【能获得的最大子串计数】                Num[i]=Num[j]+1;}int main(){    int n;    int h;    while(cin>>n){        vector<int> quene;        vector<int> incNum(n,1);  //初始化为n个1        vector<int> decNum(n,1);          vector<int> totalNum;        for(int i=0;i<n;i++){            cin >> h;            quene.push_back(h);            }        calIncSub(quene,incNum);    //找递增子串计数        reverse(quene.begin(),quene.end()); //翻转,即找反向的子串计数        calIncSub(quene,decNum);        reverse(decNum.begin(),decNum.end());   //反向递增即正向递减        int max=0;        for(int i=0;i<n;i++){            totalNum.push_back(incNum[i]+decNum[i]);            if(totalNum[i]>max)                max=totalNum[i];        }        cout << n-max+1 <<endl;    }       return 0;}
0 0
原创粉丝点击