← 返回编程题库
coding-optimal-strike-allocation困难免费版2000ms未尝试

期权价差中的最优行权价分配

Optimal Strike Allocation in Option Spread

开始编码

某波动率交易员在临近到期的同一标的、同一到期日的看涨期权链上做多腿价差结构:他要从一组离散的行权价网格里恰好挑出 K 个不同的行权价,每个行权价上买入 1 张看涨期权(不允许重复同一个行权价、不允许买分数张)。第 i 个候选行权价上一张看涨的整数权利金是 premiums[i] 美元;按当前 vol surface 估出的「每张合约期望折现收益」(已经扣过权利金,正负皆有可能)是 expected_payoffs[i] 浮点美元。账上期权预算只有整数 budget 美元。请算出:在恰好买 K 张(K 个不同行权价、每个 1 张)且总权利金 ≤ budget 的约束下,能拿到的最大期望折现收益总和。如果根本凑不出任何「恰好 K 张且权利金 ≤ budget」的可行组合,返回 -1.0

请实现 solution(premiums: list[int], expected_payoffs: list[float], budget: int, k: int) -> float。规则:(a)premiumsexpected_payoffs 等长,按下标对应同一个行权价;(b)必须恰好选 K 个不同行权价(不是「至多 K 个」——这是关键约束差异);(c)所选行权价的权利金之和必须 ≤ budget;(d)允许某些行权价的期望收益为负——若 K 太大、预算又紧,DP 可能被迫吞下亏损腿,这正是真实「行权价分配」要直面的代价;(e)若可行解不存在,返回 -1.0

示例solution([4, 5, 6, 7], [3.0, 5.0, 8.0, 10.0], 10, 2) 应返回 11.0。所有 6 个二元组:(0,1) 权利金 9 收益 8.0、(0,2) 权利金 10 收益 11.0、(0,3) 权利金 11 超预算、(1,2) 权利金 11 超预算、(1,3) 权利金 12 超预算、(2,3) 权利金 13 超预算。最优是 (0,2) = 11.0。再看 solution([4, 5, 6, 7], [3.0, 5.0, 8.0, 10.0], 14, 3):4 个三元组中 (0,1,2)=15、(0,1,3)=16、(0,2,3)=17、(1,2,3)=18 全部超 14——返回 -1.0,约束硬到不留可行点。再来 solution([1, 1, 1], [-5.0, 10.0, 20.0], 3, 2):要求恰好 2 张,三对收益 (0,1)=5、(0,2)=15、(1,2)=30,全部权利金 2 ≤ 3 可行,最优 30.0——DP 自然跳开负收益的 0 号腿。反例提示:如果你按「单位成本期望收益」贪心、再硬截到 K 个,会在带负值且 K 偏大的实例上明显失误,因为贪心不知道「凑够 K 个」这个等式约束的代价。

朴素枚举所有 C(N, K) 个子集在 N=100、K=50 时是约 10²⁹ 量级,完全不可行。关键观察是「恰好选 K 个 + 权利金总和 ≤ B」这两条约束都可以塞进 DP 状态:用 dp[j][b] 记录「已经选了 j 个行权价、权利金恰为 b」的最大期望收益,做标准 0/1 背包风格的逐资产滚动;时间复杂度 O(N · K · B),在 N=100、K=20、B=2000 下是 4×10⁶ 次基本运算,毫秒级搞定。这是 0/1 背包的「带计数约束」推广形式——也是真实期权价差结构(蝶式、铁鹰、call ladder)做行权价网格选择时的标准建模套路:连续凸优化解不动「整数张数 + 离散行权价 + 必须正好 K 条腿」的组合约束,必须落到 DP。

约束条件

  • 1 ≤ len(premiums) = len(expected_payoffs) = N ≤ 100
  • 1 ≤ K ≤ N(必须**恰好**挑 K 个不同的行权价)
  • 0 ≤ premiums[i] ≤ 2000(整数美元,单张合约的权利金)
  • −500.0 ≤ expected_payoffs[i] ≤ 500.0(浮点美元,可正可负)
  • 0 ≤ budget ≤ 2000(整数美元)
  • 若不存在恰好 K 个行权价的可行子集(其权利金总和 ≤ budget),返回 -1.0
  • 返回值允许 1e-6 浮点误差

样例

Case 1 · pick exactly 2 of 4 strikes within budget

输入: [[4,5,6,7],[3,5,8,10],10,2]

期望: 11

六个二元组:(0,1) 权利金 9 收益 8.0;(0,2) 权利金 10 收益 11.0;(0,3)、(1,2)、(1,3)、(2,3) 权利金分别 11/11/12/13 全部超 10。最优 (0,2) = 11.0。注意「按 ratio = payoff / premium 贪心 + 截到 K=2 个」会先选 (3) 比率 10/7≈1.43,再选 (2) 比率 8/6≈1.33,但两者权利金合 13 超预算——贪心连可行域都进不去,必须 DP。

Case 2 · exact-K constraint forces a negative leg

输入: [[1,1,1,1],[10,8,5,-100],4,4]

期望: -77

K = N = 4 强制选满四张,权利金合 4 ≤ 4 唯一可行子集就是全选,期望收益 10 + 8 + 5 + (−100) = −77.0。这正是「恰好 K」与「至多 K」差异显形之处:若约束放松到「至多 4」,DP 会直接跳过第 3 号腿,最优变成 23.0;但等式约束下你必须吞下亏损腿。返回**负数**也是合法答案——别误以为「答案 ≥ 0」。

最近提交

还没有提交记录。

编码区

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

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

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

Case 1 · pick exactly 2 of 4 strikes within budget

输入: [[4,5,6,7],[3,5,8,10],10,2]

期望: 11

六个二元组:(0,1) 权利金 9 收益 8.0;(0,2) 权利金 10 收益 11.0;(0,3)、(1,2)、(1,3)、(2,3) 权利金分别 11/11/12/13 全部超 10。最优 (0,2) = 11.0。注意「按 ratio = payoff / premium 贪心 + 截到 K=2 个」会先选 (3) 比率 10/7≈1.43,再选 (2) 比率 8/6≈1.33,但两者权利金合 13 超预算——贪心连可行域都进不去,必须 DP。

Case 2 · exact-K constraint forces a negative leg

输入: [[1,1,1,1],[10,8,5,-100],4,4]

期望: -77

K = N = 4 强制选满四张,权利金合 4 ≤ 4 唯一可行子集就是全选,期望收益 10 + 8 + 5 + (−100) = −77.0。这正是「恰好 K」与「至多 K」差异显形之处:若约束放松到「至多 4」,DP 会直接跳过第 3 号腿,最优变成 23.0;但等式约束下你必须吞下亏损腿。返回**负数**也是合法答案——别误以为「答案 ≥ 0」。