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\)。考虑这样一个序列:

\[(\underbrace{0, 0, \cdots, 0}_n, 1, 2, \cdots, L) \]

可以发现,从这个序列中任意选出 \(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_n^m = C_{n - 1}^m + C_{n - 1}^{m - 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, 组合数学

posted @ 2017-07-17 00:55  lijingze8  阅读(126)  评论(0)    收藏  举报