APIO2016
T1. Boat (1s, 256MB)
题目大意: 给定 \(n\) 个闭区间 \([a_i, b_i]\),现在要取 \(n\) 个数 \(s_1, s_2, \cdots, s_n\),其满足 \(s_i \in [a_i, b_i]\) 或 \(s_i = 0\)。若取的非零数单调递增,问有多少种取数方式。
数据范围: \(n \leq 500\),\(1 \leq a_i \leq b_i \leq 10^9\)
简要题解: 先考虑这样一个问题:从区间 \([1, L]\) 中取 \(n\) 个数,要求这 \(n\) 个数单调递增,求方案数。显然,答案是 \(C_L^n\),考虑只要将其选出来再排序即可。
再考虑一个类似的问题:从区间 \([1, L]\) 中取 \(n\) 个数 \(s_1, s_2, \cdots, s_n\),若 \(s_i\) 可以取零,且要求取的非零数单调递增,求方案数。这个问题的答案应为 \(C_{L + n}^n\)。考虑这样一个序列:
可以发现,从这个序列中任意选出 \(n\) 个数的方案与问题中的取数方案一一对应,对应法则如下:
- \(s_i = 0\) 等价于第 \(i\) 次取的数为零
- \(s_j = k\) 等价于将所取的非零数从小到大依次填入恰好在 \(j\) 处填入 \(k\)
若又要求 \(s_n\) 不可取零,那么方案数应为总方案数减去 \(s_n = 0\) 的方案数,即 \(C_{L + n}^n - C_{L + n - 1}^{n - 1}\)。由组合恒等式
可知方案数表达式等价于 \(C_{L + n - 1}^n\)。
下面回到原问题。为了方便处理 \(a_i = b_i\) 的情形,我们将区间 \([a_i, b_i]\) 转化为区间 \([a_i, b_i + 1)\)。将所有的区间端点排序去重后,得到端点序列 \(\{x_1, x_2, \cdots, x_{cnt}\}\)。考虑 DP,令 \(f_{ij}\) 表示取到第 \(i\) 个数,且第 \(i\) 个数取在区间 \([x_j, x_{j + 1})\) 中的方案数。注意到区间 \([a_i, b_i + 1)\) 和区间 \([x_j, x_j + 1)\) 只存在如下两种关系
- \([x_j, x_j + 1) ~ \cap ~ [a_i, b_i + 1) = \varnothing\)
- \([x_j, x_j + 1) ~ \subseteqq ~ [a_i, b_i + 1)\)
时空复杂度:
关键字: DP, 组合数学

浙公网安备 33010602011771号