1 条题解

  • 0
    @ 2025-12-9 14:21:41

    题目理解

    NN 个房间排成一条链,房间 11 有一个出口管道,需要房间 11 中至少 ee 个朋友同时按下按钮才能打开。相邻房间 iii+1i+1 之间的管道需要房间 ii 中至少 aia_i 个朋友且房间 i+1i+1 中至少 bib_i 个朋友同时按下按钮才能打开。管道打开时朋友可以自由往返。朋友一旦移动可能导致管道状态变化。

    求最多能邀请多少个朋友,使得存在一种初始的房间分配方案,使得无论朋友如何移动,都无法打开出口管道。


    算法分析

    本题需要动态规划解决,关键在于设计状态表示和转移方程。

    状态定义

    dp[i][x]dp[i][x] 表示考虑房间 ii 到房间 NN,且房间 ii 中恰好有 xx 个朋友时,从房间 ii 到房间 NN 中最多能安排的朋友总数,并且保证房间 ii 到房间 NN 之间的所有管道都不会被打开(即朋友无法从房间 ii 向右移动影响更右侧的房间,也无法从右侧房间向左移动到房间 ii)。

    转移方程

    考虑从房间 i+1i+1 向房间 ii 转移。对于房间 ii 的人数为 xx,房间 i+1i+1 的人数为 yy,要保证连接房间 iii+1i+1 的管道不会打开,需要满足:

    • xaix \ge a_i,则必须 y<biy < b_i
    • x<aix < a_i,则 yy 可以任意

    因此转移方程为:

    • x<aix < a_i,则 $dp[i][x] = x + \max\limits_{0 \le y \le lim} dp[i+1][y]$
    • xaix \ge a_i,则 $dp[i][x] = x + \max\limits_{0 \le y < b_i} dp[i+1][y]$

    其中 limlim 是一个足够大的上界。

    上界选择

    由于 e,ai,bi104e, a_i, b_i \le 10^4,可以证明每个房间的人数不需要超过 2×1042 \times 10^4 量级。实际实现中可取 lim=max(2e,max{ai+bi})lim = \max(2e, \max\{a_i + b_i\})

    初始化与答案

    对于最后一个房间 NN,没有向右的管道约束,因此:

    • dp[N][x]=xdp[N][x] = x,其中 0xlim0 \le x \le lim

    最终答案为 max0x<edp[1][x]\max\limits_{0 \le x < e} dp[1][x],因为房间 11 的人数必须小于 ee 才能保证出口管道不会直接打开。

    复杂度优化

    使用滚动数组和前缀最大值优化,可将时间复杂度优化到 O(Nlim)O(N \cdot lim),空间复杂度 O(lim)O(lim)


    算法正确性

    该动态规划从右向左递推,保证了每个管道不会被打开,从而朋友无法在房间之间移动。状态设计巧妙地将“无法打开管道”的条件转化为对相邻房间人数的约束,通过枚举当前房间人数并利用前缀最大值快速计算最优解。


    代码实现要点

    1. 使用滚动数组减少空间消耗
    2. 预处理前缀最大值加速转移
    3. 注意边界条件(N=1N=1 的情况)
    4. 合理设置上界 limlim

    算法标签

    动态规划、递推、递推、前缀优化、状态设计


    总结

    本题通过动态规划,从右向左递推,定义状态dp[i][x]表示考虑房间i到N,且房间i有x个朋友时,i到N最多能安排的朋友数,并保证管道不会被打开。转移时根据相邻管道条件(x与a_i比较决定y的范围)进行转移,并使用前缀最大值优化效率。最终答案为dp[1][x](x<e)的最大值。

    • 1

    信息

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