← 返回编程题库
coding-max-reward-trade-action-alignment困难免费版4000ms未尝试

交易动作序列的最大奖励对齐

Max-Reward Sequence Alignment Across Trade-Action Streams

开始编码

执行审计要把当日的「计划动作序列」seq_a 与撮合端实际触发的「成交动作序列」seq_b 进行对齐评分。seq_aseq_b 的每个元素都是整数交易动作码,取自 {0, 1, ..., A-1}(如 0 = BUY、1 = SELL、2 = HOLD、3 = CANCEL,字母表大小 A 上限为 8)。match_reward[a][b] 给出在对齐的同一位置上把计划动作 a 与实际动作 b 配对的奖励;该矩阵完全可参数化,可为负,且不要求对称——「实际 BUY vs 计划 SELL」的惩罚通常远大于「实际 HOLD vs 计划 HOLD」。gap_penalty 是非负整数,每当对齐在任一侧跳过一个元素(即在 seq_aseq_b 中插入一个 gap)时扣一次。

实现 solution(seq_a: list[int], seq_b: list[int], match_reward: list[list[int]], gap_penalty: int) -> int。返回所有对齐方案的最大总奖励(整数)。两条序列长度均可达 1000,因此 O(N*M) 二维 DP 完全可在限时内求解,而枚举所有对齐方案则会超时。当最优对齐仍需付 gap 或负奖励时,结果可能为负——输出是有限整数,并非非负整数。

例如 solution([0, 1, 2], [0, 2, 1], match_reward, 1),当 match_reward = [[3, -2, -1], [-1, 3, -2], [-2, -1, 3]](A=3,对角为 +3、非对角不对称落在 [-2, -1])时返回 4:最优对齐为 00+3),seq_b2 跳过(-1),11+3),seq_a2 跳过(-1),合计 +4。注意矩阵不对称:match_reward[1][2] = -2match_reward[2][1] = -1,因此 seq_a[1]=1seq_b[1]=2 同位配对严格劣于反向。当序列完全相同时 solution([0, 1, 2, 1, 0], [0, 1, 2, 1, 0], match_reward, 1) 返回 15:DP 沿对角线收 5 个 +3,因为每一步对角配对的得分都胜过 -2 的双跳代价。

当某一对的奖励很极端时——solution([0], [1], [[5, -100], [-100, 5]], 1) 返回 -2:直接对角配对会得到 match_reward[0][1] = -100;改走双侧各跳一格的路线只花 -2,严格更优。这正是「按对得分矩阵」要刻画的情形:当 match_reward[a][b] < -2 * gap_penalty 时 DP 自动选择「跳-跳」而非同位差对,无需按矩阵符号特判。把非对角项设为 0、对角设为 1gap_penalty = 0 时,递推式退化为 LC1143 的最长公共子序列;正是「按对得分矩阵」加上「gap penalty」让本题与之区别开。

实现细节由 stubs/stub.py 提供。

实践背景

合规与 TCA(Transaction Cost Analysis)桌台日常需要量化当日实际成交动作流相对于桌台计划动作流的偏离。简单计数失配数过于粗糙——它看不到不同的「同位配对」严重程度差别极大:实际 BUY 对计划 SELL 会翻转 P&L 符号、触发额外报告流程,而实际 HOLD 对计划 HOLD 几乎是 no-op。把「同位配对」按一对一对参数化打分,问题就转化为「最大奖励序列对齐」:开盘前桌台公布计划动作序列,收盘后 OMS 回放实际成交,最大总对齐奖励——由 Needleman-Wunsch 同一套二维 DP 求解——即为当日的执行质量分。关键在于:当某对的 match_reward[a][b] 极负,最优对齐自然会跳开这对差配对;当 gap penalty 很高时,对齐则尽量贴近对角线,即便要付一些较小的负奖励。DP 完全靠逐格三选一最大自动识别这两种情形,无需按矩阵符号或对称性特判——这正是「最大奖励」形式与单位权重 LCS 的本质区别。

约束条件

  • 0 <= `len(seq_a)` <= 1000
  • 0 <= `len(seq_b)` <= 1000
  • 1 <= A <= 8,A 为动作码字母表大小,`match_reward` 是 A×A 整数矩阵
  • 每个 `seq_a[i]` 与 `seq_b[j]` 取自 `{0, 1, ..., A-1}`
  • -1000 <= `match_reward[a][b]` <= 1000(可为负;矩阵不要求对称)
  • 0 <= `gap_penalty` <= 1000(整数,每次跳过任一侧元素时收取一次)
  • 两侧都为空 -> 返回 `0`;`seq_a` 为空 -> 返回 `-gap_penalty * len(seq_b)`;`seq_b` 为空 -> 返回 `-gap_penalty * len(seq_a)`
  • 最优对齐总奖励始终是有限整数(可能为负),不抛出异常

样例

Case 1 · statement-example: A=3 asymmetric matrix gap_penalty=1

输入: [[0,1,2],[0,2,1],[[3,-2,-1],[-1,3,-2],[-2,-1,3]],1]

期望: 4

A=3 reward matrix M[a][a]=3, off-diagonal in [-2,-1]; gap_penalty=1。最佳对齐为 0-0(+3), seq_b 的 2 跳过(-1), 1-1(+3), seq_a 的 2 跳过(-1),合计 +4。注意 M 不对称:M[1][2]=-2 而 M[2][1]=-1。

Case 2 · visible: identical sequences collect every diagonal reward

输入: [[0,1,2,1,0],[0,1,2,1,0],[[3,-2,-1],[-1,3,-2],[-2,-1,3]],1]

期望: 15

序列完全相同;DP 沿对角线收 5 个 +3 共 +15,因为每一步对角 M[a][a]=3 远胜 -2*gap_penalty=-2。

Case 3 · visible: very negative cross-pair plus tiny gap forces both-side gap

输入: [[0],[1],[[5,-100],[-100,5]],1]

期望: -2

diag = M[0][1] = -100;改走 gap-gap 路径只花 -2(一个 seq_a 跳和一个 seq_b 跳),明显更优。

最近提交

还没有提交记录。

编码区

实现 solution(...)。本地运行当前支持 Python 可见样例;服务端提交会运行可见样例和隐藏测试。

加载编辑器...
计时0:00

默认展示公开样例。点击「运行样例」后会在这里显示实际输出;点击「提交评测」会进入隐藏测试。

Case 1 · statement-example: A=3 asymmetric matrix gap_penalty=1

输入: [[0,1,2],[0,2,1],[[3,-2,-1],[-1,3,-2],[-2,-1,3]],1]

期望: 4

A=3 reward matrix M[a][a]=3, off-diagonal in [-2,-1]; gap_penalty=1。最佳对齐为 0-0(+3), seq_b 的 2 跳过(-1), 1-1(+3), seq_a 的 2 跳过(-1),合计 +4。注意 M 不对称:M[1][2]=-2 而 M[2][1]=-1。

Case 2 · visible: identical sequences collect every diagonal reward

输入: [[0,1,2,1,0],[0,1,2,1,0],[[3,-2,-1],[-1,3,-2],[-2,-1,3]],1]

期望: 15

序列完全相同;DP 沿对角线收 5 个 +3 共 +15,因为每一步对角 M[a][a]=3 远胜 -2*gap_penalty=-2。

Case 3 · visible: very negative cross-pair plus tiny gap forces both-side gap

输入: [[0],[1],[[5,-100],[-100,5]],1]

期望: -2

diag = M[0][1] = -100;改走 gap-gap 路径只花 -2(一个 seq_a 跳和一个 seq_b 跳),明显更优。