1 条题解

  • 0
    @ 2026-4-1 18:05:19

    题目理解

    我们有一个长度为 nn 的二进制字符串 ss 和一个参数 kk。游戏规则是:

    1. 我们选择一些位置进行保护。
    2. Teto 从左到右扫描每个位置 ii,如果满足以下三个条件,她可以将 sis_i11 改为 00
      • si=1s_i = 1
      • 该位置没有被保护
      • 前面 k1k-1 个位置(即 ik+1i-k+1i1i-1)中没有 11

    目标:选择最少的位置进行保护,使得 Teto 无法改变任何字符(即所有 11 都保持不变)。


    关键观察

    1. 保护第一个 11 是必要的
      如果字符串的第一个 11 没有被保护,且它前面没有 11(因为它是第一个),那么 Teto 就可以将它改为 00
      所以,第一个 11 必须被保护。

    2. 保护某些 11 可以阻止后续的 11 被改变
      规则中说:如果前面 k1k-1 个位置中存在 11,则当前 11 不能被 Teto 改变。
      因此,如果我们确保每个 11前面 k1k-1 个位置内至少有一个被保护的 11,那么它就不会被 Teto 改变。

    3. 只需要保护部分 11,而不是所有 11
      我们可以让某些 11 承担“保护”后续 11 的任务:
      如果一个被保护的 11 后面 k1k-1 个位置内出现了另一个 11,那么这个 11 不需要被保护,因为它前面有被保护的 11

    4. 转化问题
      我们只需要保护一些 11,使得:

      • 第一个 11 被保护;
      • 任意两个被保护的 11 之间的距离小于 kk(因为如果距离 k\ge k,中间会出现一个 11 前面没有被保护的 11,它会被 Teto 改变)。

    贪心策略

    设所有 11 的位置为 p1,p2,,pmp_1, p_2, \dots, p_m(下标从 00 开始,表示在字符串中的索引)。

    • 第一个 11 必须被保护,即 p0p_0 被保护。
    • p0p_0 开始往后看:如果 p1p0kp_1 - p_0 \ge k,说明 p1p_1 的前面 k1k-1 个位置内没有被保护的 11,那么 p1p_1 必须被保护。
    • 依此类推:我们维护最后一个被保护的 11 的位置 last\text{last},遍历所有 11,如果当前 11 的位置 ii 满足 ilastki - \text{last} \ge k,则保护它(答案加 11),并更新 last=i\text{last} = i

    算法步骤

    1. 初始化 last=\text{last} = -\infty(或者一个足够小的数,如 109-10^9)。
    2. 遍历字符串 ss 的所有位置 ii
      • 如果 s[i]=1s[i] = 1ilastki - \text{last} \ge k,则 ansans+1\text{ans} \leftarrow \text{ans} + 1,并更新 last=i\text{last} = i
    3. 输出 ans\text{ans}

    示例验证

    示例 1:n=2,k=2,s=11n=2, k=2, s=11

    • i=0i=0s[0]=1s[0]=10()20 - (-\infty) \ge 2 成立,ans=1\text{ans}=1last=0\text{last}=0
    • i=1i=1s[1]=1s[1]=110=1<21 - 0 = 1 < 2,不成立,不保护。
    • 输出 11,正确。

    示例 4:n=7,k=2,s=1010101n=7, k=2, s=1010101

    11 的位置:0,2,4,60, 2, 4, 6

    • p0p_0 被保护,last=0\text{last}=0
    • p1=2p_1=220=222-0=2 \ge 2,保护,ans=2\text{ans}=2last=2\text{last}=2
    • p2=4p_2=442=224-2=2 \ge 2,保护,ans=3\text{ans}=3last=4\text{last}=4
    • p3=6p_3=664=226-4=2 \ge 2,保护,ans=4\text{ans}=4last=6\text{last}=6
      输出 44,正确。

    示例 9:n=8,k=3,s=00000000n=8, k=3, s=00000000

    没有 11,循环不执行任何保护,ans=0\text{ans}=0,正确。


    时间复杂度

    • 遍历一次字符串,O(n)O(n)
    • nn 不超过 10001000,完全可行。

    正确性证明(归纳法)

    归纳假设:按上述贪心策略保护的 11 的集合,能够使得所有 11 在游戏过程中保持不变。

    • 基础:第一个 11 被保护,不会被改变。
    • 归纳步:假设某个被保护的 11 在位置 pp 之前的所有 11 都保持不变。
      对于下一个 11 在位置 qq
      • 如果 qp<kq - p < k,那么 qq 的前面 k1k-1 个位置中包含被保护的 pp,所以 Teto 无法改变 qq
      • 如果 qpkq - p \ge k,则 pp 的“保护范围”无法覆盖 qq,因此 qq 必须被保护,否则它前面 k1k-1 个位置没有 11,Teto 可以改变它。

    由于我们正是这样决定保护的,所以所有 11 最终都会处于被保护或被覆盖的状态,字符串保持不变。同时,这种策略显然是最优的,因为我们只在必要时才增加保护。


    总结

    本题的核心是将问题转化为:在 11 的位置序列中,如果相邻 11 的距离 k\ge k,则必须保护后一个 11
    贪心地从左到右扫描即可得到最少保护数。

    • 1

    信息

    ID
    6215
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者