1 条题解
-
0
题目理解
有 个房间排成一条链,房间 有一个出口管道,需要房间 中至少 个朋友同时按下按钮才能打开。相邻房间 和 之间的管道需要房间 中至少 个朋友且房间 中至少 个朋友同时按下按钮才能打开。管道打开时朋友可以自由往返。朋友一旦移动可能导致管道状态变化。
求最多能邀请多少个朋友,使得存在一种初始的房间分配方案,使得无论朋友如何移动,都无法打开出口管道。
算法分析
本题需要动态规划解决,关键在于设计状态表示和转移方程。
状态定义
设 表示考虑房间 到房间 ,且房间 中恰好有 个朋友时,从房间 到房间 中最多能安排的朋友总数,并且保证房间 到房间 之间的所有管道都不会被打开(即朋友无法从房间 向右移动影响更右侧的房间,也无法从右侧房间向左移动到房间 )。
转移方程
考虑从房间 向房间 转移。对于房间 的人数为 ,房间 的人数为 ,要保证连接房间 和 的管道不会打开,需要满足:
- 若 ,则必须
- 若 ,则 可以任意
因此转移方程为:
- 若 ,则 $dp[i][x] = x + \max\limits_{0 \le y \le lim} dp[i+1][y]$
- 若 ,则 $dp[i][x] = x + \max\limits_{0 \le y < b_i} dp[i+1][y]$
其中 是一个足够大的上界。
上界选择
由于 ,可以证明每个房间的人数不需要超过 量级。实际实现中可取 。
初始化与答案
对于最后一个房间 ,没有向右的管道约束,因此:
- ,其中
最终答案为 ,因为房间 的人数必须小于 才能保证出口管道不会直接打开。
复杂度优化
使用滚动数组和前缀最大值优化,可将时间复杂度优化到 ,空间复杂度 。
算法正确性
该动态规划从右向左递推,保证了每个管道不会被打开,从而朋友无法在房间之间移动。状态设计巧妙地将“无法打开管道”的条件转化为对相邻房间人数的约束,通过枚举当前房间人数并利用前缀最大值快速计算最优解。
代码实现要点
- 使用滚动数组减少空间消耗
- 预处理前缀最大值加速转移
- 注意边界条件( 的情况)
- 合理设置上界
算法标签
动态规划、递推、递推、前缀优化、状态设计
总结
本题通过动态规划,从右向左递推,定义状态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
- 上传者