1 条题解
-
0
「塔」题解
题意简化
在 整数点上造 座塔:
- 塔 高度为 (编号从 1 到 )
- 每座塔与前后相邻塔的距离 ≥ 该塔高度
- 塔的建造顺序任意(即塔的编号不一定要按位置顺序)
- 求方案数模
, 可达 。
核心观察
1. 距离条件
塔 高度为 ,所以:
- 与左边邻居距离 ≥
- 与右边邻居距离 ≥
这意味着塔的编号越大,要求间距越大。
2. 重编号
由于建造顺序任意,我们可以先决定位置,再分配编号。
考虑将塔按位置排序后,给它们分配编号 的排列 ,使得: 如果位置相邻的塔编号为 和 ,它们的间距 ≥ 。
3. 转化为排列问题
设排序后位置为 ,分配的编号为排列 。
条件:,对 。
我们要求:
- 有多少种 和排列 满足上述条件?
- 其中 ,且为整数。
关键思路:动态规划
状态设计
考虑从大到小插入塔的编号(先处理大塔,因为限制更严)。
DP状态: = 已经处理了编号最大的 个塔(编号 ),形成了 个连续段(块)的方案数。
转移
当插入编号为 的塔时(当前是第 步):
- 新建一个段:放在最左或最右,需要预留 的空间 → 方案数 (乘到系数)
- 连接两个段:放在两个段之间,需要预留 的空间(左右各 )→ 合并两个段,段数减
- 接在一个段旁边:左接或右接,需要预留 的空间 → 段数不变
但空间预留的总长度需要最后检查是否 ≤ 。
进一步转化
由于我们只关心预留空间的总长度,不关心具体位置,可以:
- 将每个塔需要的间距转化为“占用长度”
- 最后检查总占用长度是否 ≤
具体来说:
- 对于相邻塔 ,需要间距
- 如果我们按编号从大到小插入,每插入一个塔 :
- 新建段:贡献 长度(一边预留)
- 连接段:贡献 长度(两边预留)
- 接在段边:贡献 长度
所有段还会扩展,所以总占用长度 = (每个塔的贡献) + 1( 个塔占 个点,但间距占更多)
经典结论
实际上,这个问题等价于: 总占用长度 = ,其中 是塔 在排列中的“邻接次数”
更简单的公式: 总占用长度 =
最终算法
-
DP计算: = 考虑最大的 个编号,形成 个连续段,当前总占用长度为 的方案数
-
转移: 插入编号 :
- 新建段:(有 个插入位置?需要调整) 实际上,有 个空隙(包括最左最右)可新建段。
正确的:
- 新建段:
- 合并段:
- 扩展段:
-
统计答案: 最终 表示所有塔形成一个段,总占用长度 。 方案数 = 因为 是间距总长,实际占点 个,所以需要 。
复杂度优化
- ,最大占用长度 ,所以
- 很大但只用判断
- DP复杂度 可接受
关键点
- 从大到小插入编号
- 连续段DP模型
- 总占用长度公式
- 最后乘组合数确定具体位置
- 1
信息
- ID
- 5992
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者