1 条题解

  • 0
    @ 2025-10-27 17:01:10

    一、问题分析

    1.1 题目理解

    给定 NN 块牧草地组成的序列,每块牧草地上有一头奶牛(H表示荷斯坦牛,G表示更赛牛)。需要将序列划分为若干个连续的区,满足:

    • 每个区至多包含 KK 块牧草地
    • 每块牧草地恰好属于一个区
    • 最小化"更赛牛较多或均势"的区的数量

    1.2 问题转化

    对于一个区间 [j+1,i][j+1, i],判断是否为"更赛牛较多或均势":

    • 更赛牛数量 \geq 荷斯坦牛数量

    我们可以将问题转化:

    • 令 G 字符的贡献为 +1+1
    • 令 H 字符的贡献为 1-1
    • 定义前缀和 g[i]=g[i1]+(s[i]==G?1:1)g[i] = g[i-1] + (s[i] == 'G' ? 1 : -1)

    则区间 [j+1,i][j+1, i] 是"更赛牛较多或均势"当且仅当:

    g[i]g[j]0g[i] - g[j] \geq 0

    1.3 前缀和转化的严格证明

    定理1.1(前缀和等价性):对于区间 [j+1,i][j+1, i]1j+1iN1 \leq j+1 \leq i \leq N),设该区间内更赛牛的数量为 G[j+1,i]G_{[j+1,i]},荷斯坦牛的数量为 H[j+1,i]H_{[j+1,i]},则:

    $$G_{[j+1,i]} \geq H_{[j+1,i]} \iff g[i] - g[j] \geq 0 $$

    证明

    定义指示函数:

    $$\delta(k) = \begin{cases} 1 & \text{if } s[k] = 'G' \\ -1 & \text{if } s[k] = 'H' \end{cases} $$

    则前缀和定义为:

    g[i]=k=1iδ(k),g[0]=0g[i] = \sum_{k=1}^{i} \delta(k), \quad g[0] = 0

    区间 [j+1,i][j+1, i] 的前缀和差为:

    $$\begin{aligned} g[i] - g[j] &= \sum_{k=1}^{i} \delta(k) - \sum_{k=1}^{j} \delta(k) \\ &= \sum_{k=j+1}^{i} \delta(k) \\ &= \sum_{k=j+1}^{i} \mathbb{1}_{[s[k]='G']} - \sum_{k=j+1}^{i} \mathbb{1}_{[s[k]='H']} \\ &= G_{[j+1,i]} - H_{[j+1,i]} \end{aligned}$$

    其中 1[P]\mathbb{1}_{[P]} 是示性函数。

    因此:

    $$g[i] - g[j] \geq 0 \iff G_{[j+1,i]} - H_{[j+1,i]} \geq 0 \iff G_{[j+1,i]} \geq H_{[j+1,i]} $$

    定理得证。

    推论1.1:区间 [j+1,i][j+1, i] 是"更赛牛较多或均势"当且仅当 g[i]g[j]0g[i] - g[j] \geq 0

    二、算法设计

    2.1 动态规划状态定义

    定义 f[i]f[i] 表示处理前 ii 个位置时,更赛牛较多或均势的区的最小数量。

    定义2.1(合法划分):对于前 ii 个位置,一个划分 P={I1,I2,,Im}\mathcal{P} = \{I_1, I_2, \ldots, I_m\} 是合法的,当且仅当:

    1. Ik=[ak,bk]I_k = [a_k, b_k] 都是连续区间,其中 1akbki1 \leq a_k \leq b_k \leq i
    2. k=1mIk={1,2,,i}\bigcup_{k=1}^{m} I_k = \{1, 2, \ldots, i\}(覆盖所有位置)
    3. IkI=I_k \cap I_\ell = \emptyset 对于 kk \neq \ell(无重叠)
    4. IkK|I_k| \leq K 对于所有 kk(区间长度限制)
    5. b1<a2b_1 < a_2, b2<a3b_2 < a_3, ..., bm1<amb_{m-1} < a_m(按顺序排列)

    定义2.2(划分代价):对于一个合法划分 P\mathcal{P},定义其代价为"更赛牛较多或均势"的区间数:

    $$\text{cost}(\mathcal{P}) = \sum_{I \in \mathcal{P}} \mathbb{1}_{[I \text{ 是更赛牛较多或均势}]} $$

    定理2.1(状态定义正确性)f[i]f[i] 等于所有前 ii 个位置的合法划分中的最小代价:

    $$f[i] = \min_{\mathcal{P} \text{ 是合法划分}} \text{cost}(\mathcal{P}) $$

    2.2 状态转移方程

    考虑第 ii 个位置,它必须属于某个区间。设这个区间为 [j+1,i][j+1, i],则:

    • 区间长度限制:1ijK1 \leq i - j \leq K,即 max(0,iK)j<i\max(0, i - K) \leq j < i
    • 转移方程:
    $$f[i] = \min_{\max(0,i-K) \leq j < i} \left\{ f[j] + \begin{cases} 1 & \text{if } g[i] - g[j] \geq 0 \\ 0 & \text{otherwise} \end{cases} \right\} $$

    简写为:

    f[i]=minmax(0,iK)j<iC(i,j)f[i] = \min_{\max(0,i-K) \leq j < i} C(i, j)

    其中 C(i,j)=f[j]+1[g[i]g[j]0]C(i, j) = f[j] + \mathbb{1}_{[g[i] - g[j] \geq 0]}

    定理2.2(状态转移方程正确性):上述转移方程正确计算 f[i]f[i]

    证明

    (⇒)首先证明 f[i]f[i] 不大于任何合法划分的代价。

    P\mathcal{P} 是前 ii 个位置的任意合法划分,设最后一个区间为 Im=[j+1,i]I_m = [j+1, i]。则:

    • 由区间长度限制,Im=ijK|I_m| = i - j \leq K,即 jiKj \geq i - K
    • 由于 ImI_m 包含位置 ii,所以 j<ij < i
    • 因此 max(0,iK)j<i\max(0, i-K) \leq j < i

    设前 jj 个位置的划分为 P={I1,,Im1}\mathcal{P}' = \{I_1, \ldots, I_{m-1}\},则:

    $$\text{cost}(\mathcal{P}) = \text{cost}(\mathcal{P}') + \mathbb{1}_{[I_m \text{ 是更赛牛较多或均势}]} $$

    f[j]f[j] 的定义,f[j]cost(P)f[j] \leq \text{cost}(\mathcal{P}'),因此:

    $$\text{cost}(\mathcal{P}) \geq f[j] + \mathbb{1}_{[g[i]-g[j] \geq 0]} = C(i, j) $$

    由于这对任意合法的 jj 都成立,所以:

    $$\text{cost}(\mathcal{P}) \geq \min_{\max(0,i-K) \leq j < i} C(i, j) $$

    (⇐)然后证明存在一个合法划分达到这个下界。

    j=argminmax(0,iK)j<iC(i,j)j^* = \arg\min_{\max(0,i-K) \leq j < i} C(i, j)。由归纳假设,存在前 jj^* 个位置的最优划分 P\mathcal{P}^* 使得 cost(P)=f[j]\text{cost}(\mathcal{P}^*) = f[j^*]

    构造前 ii 个位置的划分 P=P{[j+1,i]}\mathcal{P} = \mathcal{P}^* \cup \{[j^*+1, i]\},则:

    $$\text{cost}(\mathcal{P}) = f[j^*] + \mathbb{1}_{[g[i]-g[j^*] \geq 0]} = C(i, j^*) = \min_{\max(0,i-K) \leq j < i} C(i, j) $$

    因此转移方程正确。

    2.3 初始状态

    f[0]=0f[0] = 0(没有任何区间)

    命题2.1(初始状态正确性):空序列的唯一合法划分是空划分,其代价为0。

    2.4 边界条件与完备性

    定理2.3(问题可解性):对于任意 1iN1 \leq i \leq N,至少存在一个 jj 使得 max(0,iK)j<i\max(0, i-K) \leq j < i

    证明

    由于 K1K \geq 1(题目保证),所以:

    • 如果 i1i \geq 1,则 j=i1j = i - 1 满足 j<ij < ijmax(0,iK)j \geq \max(0, i-K)

    因此转移方程总是有定义的。

    推论2.1:当 KNK \geq N 时,可以将整个序列划分为一个区间,问题总是有解的。

    2.5 朴素算法时间复杂度分析

    朴素的DP转移时间复杂度为 O(NK)O(NK),对于 N=3×105N = 3 \times 10^5K=NK = N 的情况,复杂度可达 O(N2)=O(9×1010)O(N^2) = O(9 \times 10^{10}),会超时,需要优化。

    三、单调队列优化

    3.1 优化思路

    观察状态转移方程,我们需要在区间 [iK,i1][i-K, i-1] 中找到使 f[j]+[g[i]g[j]0]f[j] + [g[i] - g[j] \geq 0] 最小的 jj

    关键观察:

    1. 固定 ii 时,g[i]g[i] 是常数
    2. 对于两个决策点 j1<j2j_1 < j_2,如果 j1j_1 始终不如 j2j_2 优,则 j1j_1 可以被淘汰

    3.2 单调队列维护策略

    维护一个单调队列,队列中存储的是可能成为最优决策的 jj 值。

    入队策略:对于新的位置 ii,将其加入队列前:

    • 从队尾删除所有"不如 ii 优"的元素
    • 比较标准:
      • 如果 f[i]<f[q[tail1]]f[i] < f[q[\text{tail}-1]],则 q[tail1]q[\text{tail}-1] 可以删除
      • 如果 f[i]=f[q[tail1]]f[i] = f[q[\text{tail}-1]]g[i]>g[q[tail1]]g[i] > g[q[\text{tail}-1]],则 q[tail1]q[\text{tail}-1] 也可以删除

    出队策略:超出范围 [iK,i1][i-K, i-1] 的元素从队头删除。

    决策选择:队头元素即为最优决策。

    3.3 严格数学证明

    3.3.1 问题的数学形式化

    定义3.1(代价函数):对于决策点 jj 和当前位置 ii,定义代价函数:

    $$C(i, j) = f[j] + \mathbb{1}_{[g[i] - g[j] \geq 0]} $$

    其中 1[P]\mathbb{1}_{[P]} 是示性函数:

    $$\mathbb{1}_{[P]} = \begin{cases} 1 & \text{if } P \text{ is true} \\ 0 & \text{if } P \text{ is false} \end{cases} $$

    定义3.2(决策优劣关系):对于两个决策点 j1,j2j_1, j_2 和位置 ii,称 j2j_2 不劣于 j1j_1(记为 j2ij1j_2 \preceq_{i} j_1),当且仅当:

    C(i,j2)C(i,j1)C(i, j_2) \leq C(i, j_1)

    j2j_2 严格优于 j1j_1(记为 j2ij1j_2 \prec_{i} j_1),当且仅当:

    C(i,j2)<C(i,j1)C(i, j_2) < C(i, j_1)

    3.3.2 决策支配性引理

    引理3.1(决策支配性):设 j1<j2j_1 < j_2 是两个决策点。若满足以下条件之一:

    1. f[j1]>f[j2]f[j_1] > f[j_2]
    2. f[j1]=f[j2]f[j_1] = f[j_2]g[j1]g[j2]g[j_1] \leq g[j_2]

    则对于任意 i>j2i > j_2,都有 j2ij1j_2 \preceq_{i} j_1(即 j2j_2 不劣于 j1j_1)。

    证明

    我们分两种情况讨论。

    情况1f[j1]>f[j2]f[j_1] > f[j_2]

    此时 f[j1]f[j2]+1f[j_1] \geq f[j_2] + 1(因为 ff 值均为非负整数)。

    对于任意 i>j2i > j_2,代价函数的差值为:

    $$\begin{aligned} C(i, j_1) - C(i, j_2) &= \left(f[j_1] + \mathbb{1}_{[g[i] - g[j_1] \geq 0]}\right) - \left(f[j_2] + \mathbb{1}_{[g[i] - g[j_2] \geq 0]}\right) \\ &= (f[j_1] - f[j_2]) + \left(\mathbb{1}_{[g[i] - g[j_1] \geq 0]} - \mathbb{1}_{[g[i] - g[j_2] \geq 0]}\right) \end{aligned}$$

    由于 1[P]{0,1}\mathbb{1}_{[P]} \in \{0, 1\},所以:

    $$\mathbb{1}_{[g[i] - g[j_1] \geq 0]} - \mathbb{1}_{[g[i] - g[j_2] \geq 0]} \in \{-1, 0, 1\} $$

    又因为 f[j1]f[j2]1f[j_1] - f[j_2] \geq 1,所以:

    C(i,j1)C(i,j2)1+(1)=0C(i, j_1) - C(i, j_2) \geq 1 + (-1) = 0

    因此 C(i,j2)C(i,j1)C(i, j_2) \leq C(i, j_1),即 j2ij1j_2 \preceq_{i} j_1

    情况2f[j1]=f[j2]f[j_1] = f[j_2]g[j1]g[j2]g[j_1] \leq g[j_2]

    此时代价函数的差值为:

    $$C(i, j_1) - C(i, j_2) = \mathbb{1}_{[g[i] - g[j_1] \geq 0]} - \mathbb{1}_{[g[i] - g[j_2] \geq 0]} $$

    我们需要证明:$\mathbb{1}_{[g[i] - g[j_1] \geq 0]} - \mathbb{1}_{[g[i] - g[j_2] \geq 0]} \geq 0$

    由于 g[j1]g[j2]g[j_1] \leq g[j_2],我们有:

    • 如果 g[i]g[j2]0g[i] - g[j_2] \geq 0,则 g[i]g[j1]g[i]g[j2]0g[i] - g[j_1] \geq g[i] - g[j_2] \geq 0

      此时 1[g[i]g[j1]0]=1\mathbb{1}_{[g[i] - g[j_1] \geq 0]} = 11[g[i]g[j2]0]=1\mathbb{1}_{[g[i] - g[j_2] \geq 0]} = 1

      差值 = 11=01 - 1 = 0

    • 如果 g[i]g[j2]<0g[i] - g[j_2] < 0,则可能有两种情况:

      (a) g[i]g[j1]0g[i] - g[j_1] \geq 0:此时差值 = 10=1>01 - 0 = 1 > 0

      (b) g[i]g[j1]<0g[i] - g[j_1] < 0:此时差值 = 00=00 - 0 = 0

    因此在所有情况下,都有 C(i,j1)C(i,j2)0C(i, j_1) - C(i, j_2) \geq 0,即 j2ij1j_2 \preceq_{i} j_1

    推论3.1:在单调队列中,如果 j1<j2j_1 < j_2 且满足引理3.1的条件,则 j1j_1 可以被安全删除,因为它永远不会成为最优决策。

    3.3.3 动态规划正确性证明

    定理3.1(DP最优子结构):状态转移方程

    f[i]=miniKj<iC(i,j)f[i] = \min_{i-K \leq j < i} C(i, j)

    具有最优子结构性质,即 f[i]f[i] 确实给出了前 ii 个位置的最优解。

    证明

    使用数学归纳法。

    基础情况i=0i = 0f[0]=0f[0] = 0 显然正确(空序列无需划分)。

    归纳假设:假设对于所有 k<ik < if[k]f[k] 都是前 kk 个位置的最优解。

    归纳步骤:我们需要证明 f[i]f[i] 是前 ii 个位置的最优解。

    设前 ii 个位置的任意一个合法划分方案 P\mathcal{P},设最后一个区间为 [j+1,i][j+1, i](其中 iKj<ii-K \leq j < i),前面 jj 个位置的划分为 P\mathcal{P}'

    P\mathcal{P} 中"更赛牛较多或均势"的区间数为 cost(P)\text{cost}(\mathcal{P}),则:

    $$\text{cost}(\mathcal{P}) = \text{cost}(\mathcal{P}') + \mathbb{1}_{[[j+1,i]\text{ 是更赛牛较多或均势}]} $$

    由归纳假设,P\mathcal{P}' 的最优解为 f[j]f[j],因此:

    $$\text{cost}(\mathcal{P}) \geq f[j] + \mathbb{1}_{[g[i] - g[j] \geq 0]} = C(i, j) $$

    由于 f[i]=miniKj<iC(i,j)f[i] = \min_{i-K \leq j < i} C(i, j),所以对于任意合法划分 P\mathcal{P}

    $$\text{cost}(\mathcal{P}) \geq \min_{i-K \leq j < i} C(i, j) = f[i] $$

    因此 f[i]f[i] 确实是最优解。

    定理3.2(单调队列算法正确性):使用单调队列维护的算法能够正确计算出所有的 f[i]f[i] 值。

    证明

    我们需要证明两点:

    1. 队列中始终包含最优决策点
    2. 队头始终是当前的最优决策点

    命题1(包含性):对于任意位置 ii,在计算 f[i]f[i] 时,所有可能成为最优决策的 j[iK,i1]j \in [i-K, i-1] 都在队列中,或者存在队列中的某个 jj' 使得 jijj' \preceq_{i} j

    证明:反证法。假设存在某个 jj 是最优决策但不在队列中,且队列中没有比它更优的决策。

    由于 jj 曾经被加入队列(所有位置都会加入),所以 jj 必然是被删除了。删除只有两种情况:

    (a) 从队头删除(超出范围):但 j[iK,i1]j \in [i-K, i-1],矛盾。

    (b) 从队尾删除(被更优的决策支配):存在某个 j>jj' > j 满足引理3.1的条件。由引理3.1,jijj' \preceq_{i} j,即 jj' 不劣于 jj,矛盾(因为假设 jj 是最优且队列中没有比它更优的)。

    因此假设不成立,命题1得证。

    命题2(队头最优性):在计算 f[i]f[i] 时,队头元素 q[head]q[\text{head}] 必然是所有合法决策中的最优者之一。

    证明:由队列的维护规则,队列中的元素按照"优先级"递减排列(依据引理3.1的比较标准)。队头元素是队列中"优先级"最高的,结合命题1,队头元素必然是最优决策。

    由命题1和命题2,定理3.2得证。

    3.3.4 时间复杂度严格证明

    定理3.3(时间复杂度):单调队列优化的DP算法的时间复杂度为 Θ(N)\Theta(N)

    证明

    我们分析每个元素的操作次数。

    入队操作:每个元素 i{0,1,,n}i \in \{0, 1, \ldots, n\} 最多入队一次。总入队次数 n+1=O(N)\leq n+1 = O(N)

    出队操作:分为两种:

    • 从队头出队(超出范围):每个元素最多出队一次,总次数 n+1=O(N)\leq n+1 = O(N)
    • 从队尾出队(被支配):每个元素最多出队一次,总次数 n+1=O(N)\leq n+1 = O(N)

    每个元素的生命周期:最多被入队一次,最多被出队一次。

    状态转移:对于每个 i{1,2,,n}i \in \{1, 2, \ldots, n\},执行一次 O(1)O(1) 的转移。总次数 =n=O(N)= n = O(N)

    因此,总时间复杂度为:

    T(N)=O(N)+O(N)+O(N)=O(N)T(N) = O(N) + O(N) + O(N) = O(N)

    又因为必须至少读取所有 NN 个字符,所以 T(N)=Ω(N)T(N) = \Omega(N)

    综上,T(N)=Θ(N)T(N) = \Theta(N)

    3.3.5 空间复杂度证明

    定理3.4(空间复杂度):算法的空间复杂度为 Θ(N)\Theta(N)

    证明

    算法使用的空间包括:

    • 输入数组 sO(N)O(N)
    • 前缀和数组 gO(N)O(N)
    • DP数组 fO(N)O(N)
    • 单调队列 q:最多存储 KK 个元素,O(K)=O(N)O(K) = O(N)

    总空间:S(N)=O(N)+O(N)+O(N)+O(N)=O(N)S(N) = O(N) + O(N) + O(N) + O(N) = O(N)

    又因为必须至少存储输入,所以 S(N)=Ω(N)S(N) = \Omega(N)

    综上,S(N)=Θ(N)S(N) = \Theta(N)

    四、代码实现

    4.1 核心代码分析

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 3e5 + 5;
    int n, k, f[N], g[N];
    int q[N], head, tail;
    char s[N];
    
    int main() {
        scanf("%d%d%s", &n, &k, s + 1);
    
        // 计算前缀和:G为+1,H为-1
        for (int i = 1; i <= n; i++) {
            if (s[i] == 'G')
                g[i] = g[i - 1] + 1;
            else
                g[i] = g[i - 1] - 1;
        }
    
        q[tail++] = 0; // 初始时0入队
    
        for (int i = 1; i <= n; i++) {
            // 超范围出队
            while (head < tail && i - k > q[head])
                head++;
    
            // 取出队头进行状态转移
            f[i] = f[q[head]] + (g[i] - g[q[head]] >= 0);
    
            // f[i]入队
            while (head < tail) {
                if (f[i] < f[q[tail - 1]] || 
                    (f[i] == f[q[tail - 1]] && g[i] > g[q[tail - 1]]))
                    tail--;
                else
                    break;
            }
    
            q[tail++] = i;
        }
    
        cout << f[n];
        return 0;
    }
    

    4.2 代码详解

    步骤1:前缀和预处理

    for (int i = 1; i <= n; i++) {
        if (s[i] == 'G')
            g[i] = g[i - 1] + 1;
        else
            g[i] = g[i - 1] - 1;
    }
    
    • 将字符转换为数值:G → +1,H → -1
    • 计算前缀和,便于快速判断区间的"更赛牛优势"

    步骤2:单调队列初始化

    q[tail++] = 0; // 初始时0入队
    
    • 位置0表示"空序列",是一个有效的决策点

    步骤3:DP转移(主循环)

    for (int i = 1; i <= n; i++) {
        // 出队:超出范围的决策点
        while (head < tail && i - k > q[head])
            head++;
    
        // 转移:使用队头元素
        f[i] = f[q[head]] + (g[i] - g[q[head]] >= 0);
    
        // 入队:维护单调性
        while (head < tail) {
            if (f[i] < f[q[tail - 1]] || 
                (f[i] == f[q[tail - 1]] && g[i] > g[q[tail - 1]]))
                tail--;
            else
                break;
        }
    
        q[tail++] = i;
    }
    

    单调性维护规则

    • 如果新元素 ii 比队尾元素更优(ff 值更小,或 ff 值相同但 gg 值更大),则删除队尾
    • 这样保证队列中的元素按照"优先级"单调递减

    五、样例分析

    5.1 样例输入

    7 2
    HGHGGHG
    

    5.2 计算过程

    前缀和计算

    i:    0  1  2  3  4  5  6  7
    s:    -  H  G  H  G  G  H  G
    g:    0 -1  0 -1  0  1  0  1
    

    DP过程

    ii 队列状态 队头 jj g[i]g[j]g[i] - g[j] f[i]f[i]
    1 [0] 0 -1 - 0 = -1 0 + 0 = 0
    2 [0, 1] 0 - 0 = 0 0 + 1 = 1
    3 [1, 2] 1 -1 - (-1) = 0
    4 [2, 3] 2 0 - 0 = 0 1 + 1 = 2
    5 [3, 4] 3 1 - (-1) = 2
    6 [4, 5] 4 0 - 0 = 0 2 + 1 = 3
    7 [5, 6] 5 1 - 1 = 0

    最优划分方案

    • 区间 [1, 2]:HG,均势,贡献1
    • 区间 [3, 4]:HG,均势,贡献1
    • 区间 [5, 7]:GHG,更赛牛较多,贡献1

    总计:3个"更赛牛较多或均势"的区。

    5.3 样例输出

    3
    

    六、复杂度总结

    基于第三部分的严格数学证明(定理3.3和定理3.4),我们得到:

    6.1 时间复杂度

    结论Θ(N)\Theta(N)

    详细分析

    • 前缀和预处理:O(N)O(N)
    • 单调队列DP:每个元素最多入队一次、出队一次,总操作数 O(N)O(N)
    • 状态转移:每个状态 O(1)O(1) 计算,共 NN 个状态
    • 总时间复杂度Θ(N)\Theta(N)(紧确界)

    6.2 空间复杂度

    结论Θ(N)\Theta(N)

    详细分析

    • 输入数组 sO(N)O(N)
    • 前缀和数组 gO(N)O(N)
    • DP数组 fO(N)O(N)
    • 单调队列 qO(min(K,N))=O(N)O(\min(K, N)) = O(N)
    • 总空间复杂度Θ(N)\Theta(N)(紧确界)

    6.3 复杂度优化效果

    算法 时间复杂度 空间复杂度 可通过数据规模
    朴素DP O(NK)O(NK) O(N)O(N) N104N \leq 10^4
    单调队列优化DP Θ(N)\Theta(N) N3×105N \leq 3 \times 10^5

    优化倍数:从 O(NK)O(NK)O(N)O(N),当 K=NK = N 时,优化了 NN 倍!

    七、关键技巧总结

    7.1 前缀和转化

    将"更赛牛较多或均势"的判断转化为:

    count(G)count(H)0\text{count}(G) - \text{count}(H) \geq 0

    通过前缀和快速计算区间的"优势值"。

    7.2 单调队列优化DP

    适用场景

    • 转移只依赖于一个滑动窗口内的状态
    • 存在明确的"优劣比较"规则

    优化效果

    • O(NK)O(NK) 降低到 O(N)O(N)

    7.3 决策单调性

    当前问题的决策单调性体现在:

    • 如果 f[j1]>f[j2]f[j_1] > f[j_2],则 j1j_1 永远不如 j2j_2
    • 如果 f[j1]=f[j2]f[j_1] = f[j_2]g[j1]<g[j2]g[j_1] < g[j_2],则 j1j_1 也不如 j2j_2

    八、扩展思考

    8.1 相关问题

    1. 最长不下降子序列:也可以用单调队列优化
    2. 滑动窗口最值:单调队列的经典应用
    3. 斜率优化DP:更复杂的决策单调性

    8.2 变式问题

    • 如果要求每个区间恰好包含 KK 个牧草地?
    • 如果要求最小化"荷斯坦牛较多"的区的数量?(对称问题)
    • 如果有多种奶牛种族?(多维前缀和)

    九、算法正确性完整证明总结

    9.1 证明链条

    我们的证明构成了一个完整的链条:

    定理1.1(前缀和等价性)

    区间更赛牛较多或均势    g[i]g[j]0\text{区间更赛牛较多或均势} \iff g[i] - g[j] \geq 0

    \Downarrow

    定理2.1-2.3(DP正确性)

    • 状态定义正确
    • 转移方程正确
    • 问题可解 \Downarrow

    引理3.1(决策支配性)

    $$f[j_1] > f[j_2] \text{ 或 } (f[j_1] = f[j_2] \land g[j_1] \leq g[j_2]) \implies j_2 \preceq_{i} j_1 $$

    \Downarrow

    定理3.2(单调队列正确性)

    • 队列包含所有可能最优决策
    • 队头总是最优决策 \Downarrow

    定理3.3-3.4(复杂度)

    • 时间:Θ(N)\Theta(N)
    • 空间:Θ(N)\Theta(N)
    • 1

    信息

    ID
    4266
    时间
    500ms
    内存
    128MiB
    难度
    5
    标签
    递交数
    1
    已通过
    1
    上传者