合唱队,对n个人挑出n-k个人,剩下k个人排成合唱队
来源:互联网 发布:小说逆命淘宝 编辑:程序博客网 时间:2024/06/14 02:37
题目描述:
华为机试题--
计算最少出列多少位同学,使得剩下的同学排成合唱队形
说明:
N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形。
合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2…,K,他们的身高分别为T1,T2,…,TK, 则他们的身高满足存在i(1<=i<=K)使得T1<T2<......<Ti-1<Ti>Ti+1>......>TK。
你的任务是,已知所有N位同学的身高,计算最少需要几位同学出列,可以使得剩下的同学排成合唱队形。
思想:
这道题目实质上是最长单调递增子序列的变形,如题目所示,最终的序列是先增大后减小,所以第一步,从左往右遍历找出最长的单调递增子序列,第二步,从右向左遍历找出最长的单调递增子序列,最后,将两边相加,再减一既是最后留下的k个人
具体程序如下所示:
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;
int Chorus(vector<int> str,int n)
{
vector<int> dp_1(n,1);
vector<int> dp_2(n,1);
for(int i=0;i<n;++i)
{
for(int j=i-1;j>=0;--j)
{
if(str[i]>str[j]&&dp_1[i]<dp_1[j]+1)
dp_1[i]=dp_1[j]+1;
}
}
std::reverse(dp_2.begin(), dp_2.end());
for (int i = 0; i < n; ++i)
{
for (int j = i - 1; j >= 0; --j)
{
if (str[i] > str[j] && dp_2[i] < dp_2[j] + 1)
dp_2[i] = dp_2[j] + 1;
}
}
std::reverse(dp_2.begin(), dp_2.end());
int max = -1;
int sum;
for (int i = 0; i < n; ++i)
{
sum = dp_1[i] + dp_2[i];
if (sum > max)
{
max = sum;
}
}
cout << n - max + 1 << endl;
return 0;
}
int main()
{
int n;
int temp;
vector<int> str;
while(cin>>n)
{
for(int i=0;i<n;i++)
{
cin>>temp;
str.push_back(temp);
}
Chorus(str,n);
}
return 0;
}
- 合唱队,对n个人挑出n-k个人,剩下k个人排成合唱队
- 从n个人中选择k个人的选法
- n个人排成一圈,从1开始报数,数到3,退出,剩下的最后一个人
- n个灯,k个人的开灯问题
- foj2200 n个人的环取k人且任意两个人的距离不能为2的方法数
- 递归法计算从n个人中选选k个人组成一个委员会的不同组合数
- n个人排成一圈,从1到3报数,数到3的人出列,输出最后剩下的哪个人是原来的第几号
- N个人戴帽子问题
- N个人过河问题
- Java-n个人报数
- n个不同的东西分给k个人,共有多少种分法
- 约瑟夫环问题---n个人,没弟k个剔除,最后一个元素是多少
- 组合数学之把n个不同的东西分给k个人,共有多少种分法
- 合唱队
- 合唱队
- 合唱队
- 合唱队
- 合唱队
- 1.害死人不偿命的(3n+1)猜想 (15)
- html嵌套规范
- swizzle method
- IDE_Webstorm11 激活
- 感知机与梯度下降算法
- 合唱队,对n个人挑出n-k个人,剩下k个人排成合唱队
- Zookeeper JavaApi 增删改查
- Android群英传——第五章实现滑动的7种方法(一二三)
- scrapy爬虫保存为csv文件的技术分析
- poj1144 割点模板
- shell中if条件字符串、数字比对,[[ ]]和[ ]区别
- java自定义hive sparksql thriftServer连接池
- 公共知识-Linux常用命令
- HTML/CSS学习汇总(1)