带约束的线性日期数组分类:最大化B类天数的算法设计
最大化B类日期的分配策略
你的贪心思路完全可行,而且是实现最优解的核心策略,只需要结合A类日期的存在做针对性调整即可,具体分析如下:
核心逻辑:贪心策略的合理性
要最大化B类天数,核心就是每一次都尽可能把允许的最长连续B段(14天)用满,原因很简单:
- 规则3限制单段B最多14天,多一天违规,少一天则直接浪费潜在的B天数;
- 规则4要求两段非连续B之间至少30天的非B(A/C),所以用完14天B后,必须进入冷却期,这段时间里A类日期可以直接充当冷却天数,剩下的填C,既合规又不浪费A类的“天然冷却”属性。
结合A类日期的调整细节
当遇到固定的A类时间段时,需要分场景处理:
- 正在分配B段时:一旦碰到A类日期,立刻终止当前B段(因为A类不可修改),然后从A类结束的次日开始,重新计算30天的冷却期(A类日期不计入已分配的B天数);
- 处于冷却期时:A类日期直接计入冷却天数,比如冷却期还剩15天,此时遇到一段5天的A类,冷却期直接减少5天,只需要再填10天C就可以进入下一轮B段分配;
- A类时间段覆盖冷却期时:如果整段A类的长度超过剩余冷却天数,那么冷却期直接提前完成,A类结束后即可开始分配新的B段。
迭代实现的步骤(替代递归)
用迭代遍历全年日期会比递归更高效,维护三个状态即可:
- 当前状态:可分配B/正在分配B/冷却期;
- 连续B天数计数:正在分配B时累加,达到14则切换到冷却期;
- 冷却天数计数:冷却期时累加(包括A类日期),达到30则切换回可分配B状态。
遍历过程中:
- 遇到A类日期:直接标记为A,若当前在B段则重置B计数并切换到冷却期;若在冷却期则累加冷却天数;
- 可分配B状态:开始分配B,每天累加B计数,直到满14天或遇到A类日期;
- 冷却期状态:非A类日期标记为C,累加冷却天数,直到满30天或遇到A类日期。
为什么这是最优解?
用反证法就能验证:假设存在比该贪心策略更多的B天数,那必然存在某一段可以多分配B的情况,但规则3已经锁死单段B的上限是14天,规则4要求两段之间必须30天冷却,而该策略已经把每一段能拿的B都拿满,同时用A类尽可能缩短冷却期,所以不可能存在更优的方案。
内容的提问来源于stack exchange,提问作者programmer_by_need
相关产品推荐
相关产品推荐

