赢段计数 —— 在最小长度约束下,最多不相交正和运行段的数量
Winning-Streak Counting — Maximum Disjoint Positive-Sum Runs of Minimum Length
开始编码实现 solution(returns: list[float], min_run_length: int) -> int。给定长度为 N 的每期收益序列与每段最小长度 L = min_run_length,在 returns 内尽可能多地放置不相交、连续、不重叠的子数组,使每个被放置的子数组同时满足:
- 段和严格大于
0.0; - 长度(元素个数)
>= L。
子数组之间必须不相交,但不需要覆盖整个数组 —— 段间的间隙允许存在且不被使用。返回这种合格子数组的最多数量。空输入(N == 0)返回 0。若 L > N 或没有任何合格子数组能放下,返回 0。
示例矩阵:
solution([1.0], 1)返回1(单段长度 1,和1.0 > 0)。solution([0.0], 1)返回0(段和0.0不严格大于0)。solution([1.0, 2.0], 3)返回0(L = 3 > N = 2;没有任何合规长度的运行段)。solution([1.0, -1.0], 2)返回0(唯一候选整段和0.0)。solution([1.0, -2.0, 3.0], 1)返回2(单元素[1.0]与[3.0]各自合规)。
例
solution([3.0, -1.0, 2.0, -1.0, 3.0], 2) 返回 2。L = 2 时可选不相交段 [3.0, -1.0](下标 0..1,段和 2.0 > 0)与 [-1.0, 3.0](下标 3..4,段和 2.0 > 0);下标 2 处的单元素 2.0 被跳过(单元素不满足 >= 2 的长度下界)。两段是上界:第三段长度 >= 2 至少还需要两个未用下标,而两段之间只剩下标 2 一个。对比 solution([3.0, -1.0, 2.0, -1.0, 3.0], 3) 返回 1 —— L = 3 时段 [3.0, -1.0, 2.0](段和 4.0 > 0)作为单段已合规,但两个不相交且长度 >= 3 的段至少需要 6 元素,而我们只有 5。
实践背景
研究台审视策略的每期收益流时,问的常常不是"我们最长的赢段是多少",而是"在这段窗口里,策略串起了多少独立的、长度至少 L 的赢段"。一个赢段合格当且仅当(a)它至少持续 L 个连续期(更短的小波动被视为噪声 —— 研究员要的是持续压力,不是单日昙花一现),且(b)它在该段窗内的累计收益严格为正(零和段不算赢)。赢段必须不相交 —— 一个正期不能同时算到两个不同段里 —— 段间的期数则被简单跳过(回撤、中性日、任何不构成合格赢段的元素都被无代价地略过)。研究员这样统计赢段频率,是因为它表达的是 edge 恢复的规律性:一年里有七段独立的、各 >= 5 期的赢段,与一年里只有一个跨年的大赢段,含义完全不同,即便累计 P&L 类似。段和严格大于 0 的比较器是有意为之:和恰为 0.0 的段在任何诚实意义上都不算"赢段"。
实现细节由 stubs/stub.py 提供。
约束条件
- 0 <= N <= 1500,其中 N 为 solution(returns, min_run_length) 的 returns 输入长度
- 1 <= min_run_length <= 1500;min_run_length 可以大于 N(此时没有任何长度合规的运行段能放下,答案为 0)。每个被选子数组至少包含 min_run_length 个连续元素
- 每个 returns[i] 为有限浮点数,-1e6 <= returns[i] <= 1e6(每期收益率,**不是**价格)
- 子数组合格当且仅当其和**严格大于** `0.0` 且长度 `>= min_run_length`;段和等于 `0.0` 的子数组**不**合格(比较器为 `>`,不是 `>=`)
- 返回类型为 int。被选子数组必须**不相交**且连续;被选段之间**允许**有间隙(你**不需要**覆盖整个数组)。空 returns 必须返回 0;若没有任何合格子数组能放下,返回 0(无哨兵 —— 空选取永远合法)
样例
Case 1 · statement-example: alternating returns L=2 yields two disjoint runs
输入: [[3,-1,2,-1,3],2]
期望: 2
可选 [3.0,-1.0] 段和 2.0>0 与 [-1.0,3.0] 段和 2.0>0,两段不重叠且各长度 2>=2,共 2 段;不存在 3 段不相交的合法选取。
Case 2 · statement-example: same array L=3 yields one run only
输入: [[3,-1,2,-1,3],3]
期望: 1
L=3 时单段 [3.0,-1.0,2.0] 和 4.0>0 即可获得 1 段;2 段不相交各长 >=3 共需 6 元素 > 5。
Case 3 · statement-example: L equals N collapses to single whole-array run
输入: [[3,-1,2,-1,3],5]
期望: 1
L=N=5,整段是唯一长度合规候选,和 6.0>0,1 段。
Case 4 · statement-example: empty array returns 0
输入: [[],3]
期望: 0
空数组无任何合法运行段,返回 0。
Case 5 · statement-example: L greater than N returns 0
输入: [[1,2],3]
期望: 0
L=3 > N=2,没有任何长度 >=3 的运行段能放下,返回 0。
Case 6 · statement-example: zero-sum two-element run does not qualify
输入: [[1,-1],2]
期望: 0
段和恰为 0.0,不严格大于 0,不合格;返回 0。
最近提交
还没有提交记录。
编码区
实现 solution(...)。本地运行当前支持 Python 可见样例;服务端提交会运行可见样例和隐藏测试。
默认展示公开样例。点击「运行样例」后会在这里显示实际输出;点击「提交评测」会进入隐藏测试。
Case 1 · statement-example: alternating returns L=2 yields two disjoint runs
输入: [[3,-1,2,-1,3],2]
期望: 2
可选 [3.0,-1.0] 段和 2.0>0 与 [-1.0,3.0] 段和 2.0>0,两段不重叠且各长度 2>=2,共 2 段;不存在 3 段不相交的合法选取。
Case 2 · statement-example: same array L=3 yields one run only
输入: [[3,-1,2,-1,3],3]
期望: 1
L=3 时单段 [3.0,-1.0,2.0] 和 4.0>0 即可获得 1 段;2 段不相交各长 >=3 共需 6 元素 > 5。
Case 3 · statement-example: L equals N collapses to single whole-array run
输入: [[3,-1,2,-1,3],5]
期望: 1
L=N=5,整段是唯一长度合规候选,和 6.0>0,1 段。
Case 4 · statement-example: empty array returns 0
输入: [[],3]
期望: 0
空数组无任何合法运行段,返回 0。
Case 5 · statement-example: L greater than N returns 0
输入: [[1,2],3]
期望: 0
L=3 > N=2,没有任何长度 >=3 的运行段能放下,返回 0。
Case 6 · statement-example: zero-sum two-element run does not qualify
输入: [[1,-1],2]
期望: 0
段和恰为 0.0,不严格大于 0,不合格;返回 0。