这道题的正解是 单调栈 贪心求字典序最大子序列,但是我们用朴素解法 暴力枚举所有长度为k的子序列取最大 也能在考试时拿到一定的分数。
题意:在保持相对顺序的前提下,从码流中选出恰好 k 个子包 ID,使得到的长度为 k 的序列字典序最大。输入若含非十进制数字字符则输出 error。
朴素做法:用 DFS / 回溯枚举「选或不选」当前元素,最终恰好选满 k 个,在所有候选中取字典序最大的那一个。时间约为 O(C(n,k)⋅k)。
样例和很小的 n 可以算对;当 n 接近 2000、且 k 不太小也不太大时组合数爆炸,会超时,需要后面的单调栈做法。
手机接收来自网络侧的一条码流,该码流由多个子包依次组成,每个子包拥有一个用十进制非负整数表示的子包 ID。给定数组 nums,它按原顺序记录码流中所有子包的 ID。
现在需要从码流中选出一个长度为 k 的子包 ID 集合。选择过程中可以删除若干子包,也可以一个都不删除,但剩余子包的相对顺序不能改变。按原顺序保留下来的 k 个子包 ID 构成一个子包 ID 集合。
两个长度相同的子包 ID 集合按如下规则比较优先级:从左到右逐位比较对应元素,在第一个出现不同元素的位置上,如果 a 中的数值大于 b 中对应位置的数值,则称 a 的优先级高于 b。例如,[2,5,8] 与 [2,4,9] 比较时,第一个不同位置是第二个元素,5 大于 4,因此 [2,5,8] 的优先级更高。
任务:在所有长度为 k 的子包 ID 集合中,找出优先级最高的一个。
约束条件:
2000。输入共两行。
第一行包含若干个用空格分隔的十进制非负整数,表示原始码流中的子包 ID。
第二行包含一个十进制正整数 k,表示需要选出的子包 ID 数量。
如果无法读取完整两行、某一行为空,或某一行含有除十进制数字字符和空格以外的其他字符,则视为错误输入。
对于合法输入,输出一行,将优先级最高的子包 ID 集合中的 k 个 ID 用空格分隔打印出来。
对于错误输入,输出 error。
输入
3 1 2 5 4
3
输出
3 5 4
说明
原始码流为 [3,1,2,5,4],需要选出 k=3 个子包 ID。
首元素如果取 5,后面只剩 [4],数量不足以再选 2 个 ID,所以首元素最大可取 3。首元素为 3 时,第二个元素最大可取 5,此时后面还剩 [4],刚好选满。
因此优先级最高的集合为 [3, 5, 4],输出 3 5 4。
输入
1 5 2 5 3
1
输出
5
说明
当 k=1 时,只需要保留 1 个子包 ID。
此时优先级比较退化为单个数值比较,数值越大优先级越高。码流中的最大 ID 是 5,因此输出 5。
虽然码流中有两个 5,但输出数值不受位置影响。
输入
2 9 3 8 7
5
输出
2 9 3 8 7
说明
需要选出的长度 k=5 等于原始子包数量 5。
因此不能删除任何子包,所有 ID 必须按原顺序全部保留。
所以输出原码流 2 9 3 8 7。
Scan the QR code below with WeChat to sign in
First-time scan will create your account automatically
请使用微信扫描下方二维码完成注册