UVa 1393 Highways (动态规划)
题目
题目大意
有一个\(n\)行\(m\)列(\(1 ≤ n, m ≤ 300\))的点阵, 问: 一共有多少条非水平非竖直的直线至少穿过其中两个点? 例如, \(n = 2\), \(m = 4\)时答案为\(12\), \(n = m = 3\)时答案为\(14\)。
题解
首先考虑如何判断是否形成一条之前没有出现过的直线, 如果它向量两坐标的最大公约数为\(1\)则没有出现过。我们考虑用\(dp_{i\ j}\)表示表示向量\((x, y)\)(\(x ≤ i\), \(y ≤ j\))共有多少个\((x, y) = 1\)的, 递推式为:
\[dp_{i\ j} = dp_{i - 1\ j} + dp_{i\ j - 1} - dp_{i - 1\ j - 1} ((i, j) ≠ 1)\]
\[dp_{i\ j} = dp_{i - 1\ j} + dp_{i\ j - 1} - dp_{i - 1\ j - 1} + 1 ((i, j) = 1)\]
接下来处理所有点, 到\((i, j)\)时, 内部各点与他组成的向量范围都在\(\{(x, y)|x∈[1, i), y∈[1, j), x, y∈N^*\}\)内, 那么可以用\(dp_{i - 1\ j - 1}\)表示其中有多少与其互质, 再减去重复计算的(\(dp_{\frac{i - 1}{2}\ \frac{j - 1}{2}}\))。为了方便我们将所有\(i\), \(j\)增加\(1\), 最后减\(1\)即可。
代码
1 |
|