QOJ2568 Mountains
个人记录第二十三篇。
这个题完全可以把 \(n\) 和 \(m\) 开的更大然后 \(k\) 开到 \(\inf\) 的。
题意
有一个 \(n\times m\) 的网格图,格子 \((i,j)\) 里面填有非负整数 \(a_{i,j}\)。现在你从 \((1,1)\) 出发,每次可以走到 \((i+1,j)\) 或者 \((i,j+1)\),最终走到 \((n,m)\)。由于你的特殊喜好,你只想走 \(a_{i,j}\) 之和(称为这条路径的权值)最大的一条路径。现在你想知道,有多少种这样的网格图,能够使最大权值小于等于 \(k\)。
\(1\le n,m,k\le100\)。
Solution
看着很像一个 dp 对吧,那不妨从 dp 的角度考虑。
设 \(dp_{i,j}\) 表示从 \((1,1)\) 走到到 \((i,j)\) 的最大路径权值,可以得到 \(dp_{n,m}\le k\)。显然有转移 \(dp_{i,j}=a_{i,j}+\max\{dp_{i-1,j},dp_{i,j-1}\}\)。所以 \(a_{i,j}=dp_{i,j}-\max\{dp_{i-1,j},dp_{i,j-1}\}\)。
因为 \(a_{i,j}\ge 0\),所以 \(dp_{i,j}\ge\max\{dp_{i-1,j},dp_{i,j-1}\}\)。
容易发现,\(dp_{1,1}\ge\max\{dp_{0,1},dp_{1,0}\}=\max\{0,0\}=0\),所以 \(0\le dp_{1,1}\le k\)。
根据转移过程中每个 \(dp\) 值的变化,可以得到 \(0\le dp_{i,j}\le k\)。
于是问题转化成:求有多少个 \(n\times m\) 的矩阵,满足里面每个元素在 \([0,k]\) 范围内,并且每一行从左至右单调不降,每一列从上到下单调不降。
求这个东西有一个著名的公式,叫 Macmahon 公式(尽管我从未听说过有这个东西):
证明我不会,据说跟杨表有关。
因为 \(1\le n,m,k\le100\),所以直接暴力算就行了,复杂度 \(O(nmk)\),可以通过。
加强版
如果现在 \(1\le n,m\le 5000,1\le k\le 10^9\),怎么做?
之前的 \(O(nmk)\) 已经不再适用了。考虑优化这个公式。
将第三层求积式展开:
可以发现有一堆分子和分母被消去了。最终剩下的是
恭喜你找到了复杂度与 \(k\) 无关的 \(O(nm)\) 做法。
加强加强版
现在 \(1\le n,m\le 10^6,1\le k\le 10^9\),怎么做?
我们需要一个线性做法。考虑继续优化这个式子。你会发现原式中有很多项是一样的。于是容易想到:我们直接将这些相同的项统一乘起来来降低复杂度。
似乎这些项是有规律可循的?注意到每一项都包含 \(i+j\),好像能用格点图来解释。将格点图中行数加列数相等(\(i+j\) 相等)的格点连成一条线。

可以发现图中红线经过的格子数是先增大后减小的,并且对于 \(i+j\) 和 \(n+m-i-j\),它们对应的格子数相等。
所以对于原式中的每一项,它被乘的次数就是对应 \(i+j\) 的红线经过的格子数。
设 \(t=i+j\),\(c_t\) 表示 \(t\) 这条红线经过的格子数,显然有 \(c_t=\min\{t-1,n,m,n+m-t+1\}\)。于是答案即为
于是我们有了这道题的 \(O(n+m)\) 做法。

浙公网安备 33010602011771号