← 返回编程题库
coding-max-reward-with-action-switch-penalty中等免费版2000ms未尝试

三态动作路径 —— 含每次切换平摊惩罚的最大累计奖励

Three-State Action Path — Max Cumulative Reward With Flat Per-Flip Switching Penalty

开始编码

实现 solution(reward: list[list[float]], switch_penalty: float) -> float。决策台账在 N 个连续日子上,每天从三个抽象动作槽位 a ∈ {0, 1, 2} 中挑一个执行。第 d 天选动作 a 当天获得奖励 reward[d][a](一个按天按动作给出的二维奖励表,作为输入直接给出)。当第 d 天(d >= 1)选择的动作与第 d - 1 天不同时,触发一次平摊切换惩罚 switch_penalty >= 0,其金额对所有动作对都相同;第 0 天没有惩罚,第 N - 1 天之后也没有末期惩罚。

返回 sum_d reward[d][a_d] - switch_penalty * count(d > 0 and a_d != a_{d-1}) 在所有动作序列 a_0, a_1, ..., a_{N-1} ∈ {0, 1, 2}^N 上的最大值。若 N = 0,返回 0.0

solution([[1.0, 0.0, -0.5], [-0.5, 1.0, 0.0], [0.0, -0.5, 1.0], [1.0, 0.0, -0.5]], 0.5) 返回 2.5。取 a = [0, 1, 2, 0] 收集到 4 天奖励 1.0 + 1.0 + 1.0 + 1.0 = 4.0,但要支付 3 次 0.5 的切换惩罚,净 4.0 - 1.5 = 2.5。坚持动作 0 全程仅得 1.0 + (-0.5) + 0.0 + 1.0 = 1.5,明显更差。同一奖励矩阵下,若 switch_penalty = 0.0 则最优为每日 argmax 之和 4.0;若 switch_penalty = 1000.0 则最优塌缩为始终持有动作 0,返回 1.5

实践背景

regime-aware 的仓位规模决策台账每天从三个仓位状态中挑一个 —— 此处抽象为槽位 {0, 1, 2}(可类比为多 / 平 / 空,或某规模规则下三档离散目标权重)。该台账由独立信号模型在上游算出每天每个动作的预期奖励表,作为输入 reward 直接给出,不是价格序列。每天相对前一天的仓位变更要付一次平摊运营成本(手续费、滑点、唤醒下游账本的开销),其大小不依赖于前后两个状态是哪一对(与"切换矩阵"模型相对,是"扁平税率"模型)。台账想知道:在当前 switch_penalty 标定下、事后完美择时所能达到的累计奖励上界是多少,以便候选信号模型在"捕获率"口径上被合理评估。switch_penalty -> 0 时该上界塌缩为每日 argmax 之和(高估了切换活动的容忍度);当 switch_penalty 大到足以使该时间窗上任何切换路径相对"挑一个槽位永不动"的累计奖励增益都不足以覆盖一次切换成本时,该上界又塌缩为"挑一个槽位永不动"(低估了切换活动)。真正有意义的区间在两端之间 —— DP 每天做的"维持 vs 切换"决策,恰好刻画了实盘台账每天面对的取舍。

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

约束条件

  • 0 <= N <= 5000,其中 N 为天数(`reward` 的行数)
  • `reward` 每行恰好包含 3 个元素,每个为有限浮点数,-1e6 <= reward[d][a] <= 1e6
  • 0.0 <= switch_penalty <= 1e6;switch_penalty 为有限非负浮点数,仅在每天相对前一天动作发生变化时收取一次,对所有动作对收取的金额相同
  • 不存在隐式的"前一动作":第 0 天可免费任选三种动作之一;末期亦不收取任何惩罚
  • 输出为有限浮点数;比较器为 float,rel_tol = 1e-9,abs_tol = 1e-9。空 `reward`(N = 0)必须返回 0.0

样例

Case 1 · statement-example: 4-day diag-rotation with switch_penalty=0.5

输入: [[[1,0,-0.5],[-0.5,1,0],[0,-0.5,1],[1,0,-0.5]],0.5]

期望: 2.5

切换贪心选 [0,1,2,0] 净 4.0 - 3 x 0.5 = 2.5;坚持单一动作 0 仅得 1.5;最优为 2.5。

Case 2 · statement-example: switch_penalty=0 collapses to per-day argmax

输入: [[[1,0,-0.5],[-0.5,1,0],[0,-0.5,1],[1,0,-0.5]],0]

期望: 4

switch_penalty=0 时无切换成本,每日独立取最大:1.0+1.0+1.0+1.0 = 4.0。

Case 3 · statement-example: huge switch_penalty forces single-action path

输入: [[[1,0,-0.5],[-0.5,1,0],[0,-0.5,1],[1,0,-0.5]],1000]

期望: 1.5

switch_penalty=1000 远大于任何切换收益,最优为坚持动作 0 全程:1.0 + (-0.5) + 0.0 + 1.0 = 1.5。

最近提交

还没有提交记录。

编码区

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

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

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

Case 1 · statement-example: 4-day diag-rotation with switch_penalty=0.5

输入: [[[1,0,-0.5],[-0.5,1,0],[0,-0.5,1],[1,0,-0.5]],0.5]

期望: 2.5

切换贪心选 [0,1,2,0] 净 4.0 - 3 x 0.5 = 2.5;坚持单一动作 0 仅得 1.5;最优为 2.5。

Case 2 · statement-example: switch_penalty=0 collapses to per-day argmax

输入: [[[1,0,-0.5],[-0.5,1,0],[0,-0.5,1],[1,0,-0.5]],0]

期望: 4

switch_penalty=0 时无切换成本,每日独立取最大:1.0+1.0+1.0+1.0 = 4.0。

Case 3 · statement-example: huge switch_penalty forces single-action path

输入: [[[1,0,-0.5],[-0.5,1,0],[0,-0.5,1],[1,0,-0.5]],1000]

期望: 1.5

switch_penalty=1000 远大于任何切换收益,最优为坚持动作 0 全程:1.0 + (-0.5) + 0.0 + 1.0 = 1.5。