P7154 Sleeping Cows 题解
题意:给定两个数组 \(a_i,b_i\),若 \(a_i\le b_j\),则他俩可配对。求极大匹配的方案数。(极大不是最大,最大一定是极大)
先考虑最大匹配方案数怎么求。
把 \(a\) 和 \(b\) 从小到大排序。则每个 \(a_i\) 能匹配的 \(b\) 都是一段后缀,且随着 \(i\) 增大,这个后缀越来越小。
于是从 \(a_n\) 向 \(a_1\) 遍历,如果现在遍历到 \(a_i\),且 \(a_i\) 能匹配 \(b_j\sim b_n\)。令答案乘以 \((n-j+1)-(i-1)\),即原本 \(n-j+1\) 个选择,前面的消耗了 \(i-1\) 个。
接下来考虑极大匹配方案数。
怎么描述一个匹配是 “极大” 的?
对于一个匹配,找到其最小的没有匹配上的 \(a_i\) 和最大的没有匹配上的 \(b_j\)。若 \(a_i\) 和 \(b_j\) 无法匹配,则这个匹配就是极大的。
证明:因为 \(a_i,b_j\) 无法匹配,则 \(a_{i+1\sim n},b_{1\sim j-1}\) 也都无法匹配了。
于是枚举最小的没匹配上的 \(a_i\),由此求出最小的能匹配上 \(a_i\) 的 \(b_t\)。显然 \(b_{t\sim n}\) 必须满配,否则 \(a_i\) 与它们之一可以使匹配数量加一。
同时注意 \(a_{1\sim i-1}\) 也要满配,不然与 \(a_i\) 的 “最小” 矛盾。
因此枚举完 \(a_i\),再枚举 \(a_{1\sim i-1}\) 和 \(b_{t\sim n}\) 之间匹配的对数 \(j\)。(显然这里要满足 \(j\le \min(i-1,n-t+1)\))
假如能求出两个数组:\(f[i][j]\) 表示 \(b_1\sim b_i\) 配出去 \(j\) 条边的方案数;\(g[i][j]\) 表示 \(a_{i+1}\sim a_n\) 配出去 \(j\) 条边的方案数。
则答案即为 $$\sum_{i,j} f[t-1][i-1-j]\cdot g[i+1][(n-t+1)-j]\cdot j!$$
解释一下。\(\sum_{i,j}\) 就是枚举 \(i,j\)。既然 \(a_1\sim a_{i-1}, b_t\sim b_n\) 匹配了 \(j\) 条,且它们俩都要满配,所以 \(a_1\sim a_{i-1}, b_1\sim b_{t-1}\) 匹配了 \((i-1)-j\) 条,\(a_{i+1}\sim b_t\sim b_n\) 匹配了 \((n-t+1)-j\) 条。
而 \(a_1\sim a_{i-1}, b_1\sim b_{t-1}\) 匹配了 \((i-1)-j\) 条的方案数恰好就是 \(f[t-1][(i-1)-j]\)。
为什么?\(f\) 的定义是 \(b_1\sim b_{t-1}\) 能匹配 \(a_1\sim a_n\),现在只匹配 \(a_1\sim a_{i-1}\),为什么对?
这是因为 \(b_t\) 已经是最小的能匹配 \(a_i\) 的了。所以 \(b_1\sim b_{t-1}\) 都匹配不了 \(a_i\),所以 \(b_1\sim b_{t-1}\) 实际上也就只能匹配 \(a_1\sim a_{i-1}\)。
同理,\(a_{i+1}\sim b_t\sim b_n\) 匹配了 \((n-t+1)-j\) 条 的方案数是 \(g[i+1][(n-t+1)-j]\)。
在 \(a_{i+1}\sim a_n,b_1\sim b_{t-1}\) 匹配完上面的之后,\(a_1\sim a_{i-1},b_t\sim b_n\) 都还剩 \(j\) 个没匹配。因为 \(a_i\) 都能匹配 \(b_t\sim b_n\),所以 \(a_1\sim a_{i-1},b_t\sim b_n\) 就是随便匹配,方案数是 \(j!\)。
总结:要学会排序简化计数。要学会用 DP 预处理辅助数组,加速计数。