← 返回编程题库
coding-smallest-position-meeting-risk-budget中等免费版2000ms未尝试

首次触及风险预算的最小持仓数量

Smallest Position Size Meeting Risk Budget

开始编码

风控部门要给一只新策略上线作日内风险预算监控。 策略每开一手仓位都会消耗一定的「风险预算」(按照部门内部的 VaR 度量计算)。 经过一轮回归拟合,风控团队把单日仓位 s 的风险预算消耗简化成一个两参数模型:

risk(s) = unit_risk * s + concentration * s²

其中 unit_risk 是每增加一手的线性风险贡献(按持仓基准 VaR 估算), concentration * s² 是「持仓集中度惩罚」——仓位越大,分散化效应越弱、单位风险增量越高。 两个参数都是非负的,因此 risk(s)s = 0, 1, 2, ... 上单调不减。

风控想知道一个关键的预警阈值:**当持仓增长到多少手时,累积风险首次达到(或超过)当日的风险预算 budget?** 这个数字决定了交易台何时收到「再加仓就要破限额」的告警。 请实现 solution(unit_risk: float, concentration: float, budget: float, max_size: int) -> int, 返回**满足 risk(s) >= budget 的最小非负整数 s**(其中 s 限定在 [0, max_size])。 如果在整个区间内累积风险都达不到预算(即 risk(max_size) < budget),返回 -1——意味着今天的预算还没被这只策略吃掉。

例如 solution(2.0, 0.5, 100.0, 1000) 应返回 13: 逐步代入 risk(12) = 2*12 + 0.5*144 = 24 + 72 = 96 < 100, 而 risk(13) = 2*13 + 0.5*169 = 26 + 84.5 = 110.5 >= 100。 13 是首次让累积风险跨过 100 这条预算线的最小整数仓位。

朴素地在 s = 0, 1, 2, ..., max_size 上线性扫描在 max_size = 10⁹ 时会跑爆 2 秒的时间限制, 而 risk(s) 又有解析的二次形式,理论上可以套求根公式直接求解—— 但浮点解开方再 ceil 容易在 concentration 接近 0 或参数极大时引入 1 ulp 的整数偏差。 更稳健的做法是**在整数 s 上做二分**:每次 O(1) 调用 risk(mid),30 多步内即可锁定答案,对参数边角无任何脆弱性。 这正是「binary search on the answer」的经典入门——目标本身就是答案,搜索空间就是答案的取值区间。

参考实现见 stubs/stub.py

约束条件

  • 0.0 ≤ unit_risk ≤ 1e6
  • 0.0 ≤ concentration ≤ 1e6
  • 0.0 ≤ budget ≤ 1e18
  • 1 ≤ max_size ≤ 1e9
  • 返回 `int`:满足 `risk(s) >= budget` 的最小非负整数 `s`,其中 `risk(s) = unit_risk * s + concentration * s * s`
  • 若 `risk(max_size) < budget`(即整段区间都达不到预算),返回 -1
  • 若 `budget == 0`,答案是 0(因为 `risk(0) = 0 >= 0`)
  • 禁止线性扫描 0..max_size——max_size 可达 10⁹,线性会 TLE

样例

Case 1 · statement example: linear + quadratic

输入: [2,0.5,100,1000]

期望: 13

risk(s) = 2s + 0.5s²。risk(12) = 24 + 72 = 96 < 100;risk(13) = 26 + 84.5 = 110.5 ≥ 100。13 是首次跨过预算线的最小整数仓位。

Case 2 · pure linear: zero concentration penalty

输入: [10,0,95,1000]

期望: 10

concentration = 0 时模型退化为纯线性 risk(s) = 10s。要 10s ≥ 95,最小整数 s = 10。注意 ceil(95/10) = 10,而不是 9.5。

最近提交

还没有提交记录。

编码区

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

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

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

Case 1 · statement example: linear + quadratic

输入: [2,0.5,100,1000]

期望: 13

risk(s) = 2s + 0.5s²。risk(12) = 24 + 72 = 96 < 100;risk(13) = 26 + 84.5 = 110.5 ≥ 100。13 是首次跨过预算线的最小整数仓位。

Case 2 · pure linear: zero concentration penalty

输入: [10,0,95,1000]

期望: 10

concentration = 0 时模型退化为纯线性 risk(s) = 10s。要 10s ≥ 95,最小整数 s = 10。注意 ceil(95/10) = 10,而不是 9.5。