1 条题解

  • 0
    @ 2025-10-29 14:55:34

    一、题意理解

    nn 个坑,按顺序播种。

    • 每个坑播种需要 11 单位时间。
    • ii 个坑有概率 pip_i 播错种子。
    • 铲除一个种子也需要 11 单位时间。
    • 在任何时刻,可以花费 tt 时间检查 所有已播种的坑,然后从当前坑往前一直铲到 第一个出错的位置(包括这个位置)。

    目标是:选择最优的检查策略,使得播完所有坑的 期望时间 最小。


    二、关键点分析

    1. 检查的作用
      如果发现错误,可以立即铲除从当前坑到第一个错误之间的所有种子(包括错误位置),避免后续在这些错误基础上继续播种浪费更多时间。

    2. 铲除规则
      假设当前检查时已经播种到位置 kk,检查发现最早出错的坑是 jj1jk1 \le j \le k),那么需要铲除 j,j+1,,kj, j+1, \dots, k 这些坑的种子,铲除时间 = 这些坑的数量。

    3. 决策点
      我们可以在播种任意一个坑之后决定是否检查。最优策略是动态决定何时检查,以最小化总期望时间。


    三、动态规划状态设计

    dp[i]dp[i] 表示 已经正确播种完前 ii 个坑 的最小期望时间。

    注意这里“正确播种完”意味着:

    • ii 个坑都播种过且当前没有错误(可能经过检查铲除后重新播种正确)。

    初始:dp[0]=0dp[0] = 0(没有坑时时间为 0)。


    四、状态转移

    考虑从 dp[i]dp[i] 转移到 dp[j]dp[j]j>ij > i):

    策略:从第 i+1i+1 个坑开始播种,一直播种到第 jj 个坑,然后进行一次检查。

    1. 播种阶段

    播种 jij-i 个坑,时间 = jij-i

    2. 检查阶段

    花费 tt 时间检查。

    3. 可能的结果

    检查时,我们看前 jj 个坑中 最早出错 的位置。

    设最早出错位置是 kki+1kji+1 \le k \le j)的概率:

    • ii 个坑保证正确(因为 dp[i]dp[i] 状态是正确播种完前 ii 个坑)。
    • 所以最早出错位置 kk 必须满足:i+1i+1k1k-1 全对,第 kk 个错。

    概率 = (1pi+1)(1pi+2)(1pk1)pk(1-p_{i+1})(1-p_{i+2})\dots(1-p_{k-1}) \cdot p_k

    如果 k=j+1k = j+1 表示 i+1i+1jj 全对,概率 = r=i+1j(1pr)\prod_{r=i+1}^j (1-p_r)


    4. 铲除与恢复时间

    如果最早出错在 kki+1kji+1 \le k \le j):

    • 需要铲除 kkjj 的种子,数量 = jk+1j-k+1
    • 然后从 kk 开始重新正确播种到 jj,这部分的期望时间 = dp[j]dp[k1]dp[j] - dp[k-1]

    如果全对(k=j+1k = j+1):

    • 不需要铲除,直接进入状态 dp[j]dp[j],额外时间 = 00

    五、转移方程

    Pall(i+1,j)=r=i+1j(1pr)P_{\text{all}}(i+1, j) = \prod_{r=i+1}^j (1-p_r)

    那么: $ dp[j] = \min_{0 \le i < j} \left\{ dp[i] + (j-i) + t + \sum_{k=i+1}^j \left[ \left( \prod_{r=i+1}^{k-1} (1-p_r) \right) p_k \cdot \big( (j-k+1) + (dp[j] - dp[k-1]) \big) \right] \right\} $ 其中对于 k=j+1k = j+1(全对)的情况,贡献为 Pall(i+1,j)0P_{\text{all}}(i+1, j) \cdot 0,已经隐含在求和中(kk 只到 jj)。


    但这里 dp[j]dp[j] 出现在等式两边,需要整理。

    设 $A = dp[i] + (j-i) + t + \sum_{k=i+1}^j \left[ \left( \prod_{r=i+1}^{k-1} (1-p_r) \right) p_k \cdot (j-k+1) \right]$
    设 $B = \sum_{k=i+1}^j \left[ \left( \prod_{r=i+1}^{k-1} (1-p_r) \right) p_k \cdot dp[k-1] \right]$

    那么: $ dp[j] = A - B + \left( \sum_{k=i+1}^j \left[ \left( \prod_{r=i+1}^{k-1} (1-p_r) \right) p_k \right] \right) dp[j] $

    设 $C = \sum_{k=i+1}^j \left[ \left( \prod_{r=i+1}^{k-1} (1-p_r) \right) p_k \right]$,则: dp[j](1C)=AB dp[j] (1 - C) = A - B 注意 C+Pall(i+1,j)=1C + P_{\text{all}}(i+1, j) = 1,因为这是所有可能情况。

    所以 1C=Pall(i+1,j)1 - C = P_{\text{all}}(i+1, j)

    因此: dp[j]=ABPall(i+1,j) dp[j] = \frac{A - B}{P_{\text{all}}(i+1, j)}


    六、最终转移方程

    对于 0i<j0 \le i < j: $ dp[j] = \min \left\{ \frac{ dp[i] + (j-i) + t + \sum_{k=i+1}^j \left[ \left( \prod_{r=i+1}^{k-1} (1-p_r) \right) p_k \cdot (j-k+1) \right] - \sum_{k=i+1}^j \left[ \left( \prod_{r=i+1}^{k-1} (1-p_r) \right) p_k \cdot dp[k-1] \right] }{ \prod_{r=i+1}^j (1-p_r) } \right\} $


    七、算法实现

    我们可以用动态规划,在计算 dp[j]dp[j] 时枚举 ii,并维护前缀积来快速计算概率乘积。

    复杂度 O(n3)O(n^3) 可优化到 O(n2)O(n^2),因为 n3000n \le 3000O(n2)O(n^2) 可过。


    八、样例验证

    样例:

    n=3, t=1
    p = [0.00001, 0.5, 0.00001]
    

    输出:8.000080000800008

    用上述 DP 计算可得该结果。


    九、代码框架(C++)

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    const int N = 3006;
    
    int n, t;
    double p[N], f[N];
    
    int main() {
    #ifdef Ezio
        freopen("10.in", "r", stdin);
        freopen("10.out", "w", stdout);
    #endif
        scanf("%d%d", &n, &t);
    
        for (int i = 1; i <= n; i++)
            scanf("%lf", &p[i]), p[i] = 1 - p[i];
    
        f[n] = 0;
    
        for (int i = n - 1; i >= 0; i--) {
            double cur = t + 1 + (1 - p[i + 1]) + p[i + 1] * f[i + 1];
            double temp = p[i + 1];
            f[i] = cur;
    
            for (int j = 2; i + j <= n; j++) {
                temp *= p[i + j];
                cur += 2 - temp + temp * f[i + j] - temp * f[i + j - 1];
                f[i] = std::min(f[i], cur);
            }
    
            f[i] /= p[i + 1];
        }
    
        printf("%.8lf\n", f[0]);
        return 0;
    }
    

    十、总结

    本题的关键在于:

    1. 将最优检查策略建模为动态规划。
    2. 状态 dp[i]dp[i] 表示正确播种前 ii 个坑的最小期望时间。
    3. 转移时考虑从 ii 播种到 jj 后检查,根据最早出错位置计算期望时间。
    4. 利用概率公式化简转移方程。

    该解法可以处理 n3000n \le 3000 的数据范围。

    • 1

    信息

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