华为机考题笔记
1.华为OJ 合唱队
原创 2016年07月31日 20:37:28 标签:C++ /华为OJ /动态规划 1368
描述
说明:
N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形。
合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2…,K,他们的身高分别为T1,T2,…,TK, 则他们的身高满足存在i(1<=i<=K)使得Ti<T2<......<Ti-1<Ti>Ti+1>......>TK。
你的任务是,已知所有N位同学的身高,计算最少需要几位同学出列,可以使得剩下的同学排成合唱队形。
知识点 循环
运行时间限制 0M
内存限制 0
输入
整数N
一行整数,空格隔开,N位同学身高
输出
最少需要几位同学出列
样例输入 8 186 186 150 200 160 130 197 200
样例输出 4
一道动态规划的例子。
刚开始没用动态规划的方法做,考虑的是将各点分别作为最高的点来处理,先往左遍历,发现左边的数比当前数字高,就去除左边的数字并计数,而且再把它的值降为当前数字。然后再向右处理。最后比较最小值。这样做始终通不过,后来发现这是一种错误的思路。
正确的解法:
用input[i]表示输入的数字;
用left[i]表示从左边第一个数到第i个数最大的增长序列个数;
用right[i]表示从右边最后一个数到第i个数最大的增长序列个数;
结果就是 n - max(left[i] + right[i] -1)
解释:
max(left[i] + right[i] - 1)表示的是合唱队最多的人数,相反的情况就是最少需要几位同学出列
代码中最关键的一行是 left[i] < left[j] + 1 代表的意思是目前的这个left[j] + 1是否比之前得到的 left[i] 要大。假设之前left[i] = 4,现在left[j] + 1 = 3,那么就不需要更新。
2.数据分类处理:
从R依次中取出R<i>,对I进行处理,找到满足条件的I<j>:
I<j>整数对应的数字需要连续包含R<i>对应的数字。比如R<i>为23,I<j>为231,那么I<j>包含了R<i>,条件满足 。
按R<i>从小到大的顺序:
(1)先输出R<i>;
(2)再输出满足条件的I<j>的个数;
(3)然后输出满足条件的I<j>在I序列中的位置索引(从0开始);
(4)最后再输出I<j>。
附加条件:
(1)R<i>需要从小到大排序。相同的R<i>只需要输出索引小的以及满足条件的I<j>,索引大的需要过滤掉
(2)如果没有满足条件的I<j>,对应的R<i>不用输出
(3)最后需要在输出序列的第一个整数位置记录后续整数序列的个数(不包含“个数”本身)
一定要记得处理多个case,并且多个case之间要cout<<endl
一个case中,最后的输出数字后面不能多加“ ”空格

浙公网安备 33010602011771号