HDU - 5698 瞬间移动 组合数学 思维
HDU - 5698 瞬间移动 组合数学 思维
题意
给一个无限大的方形网络,从\((1,1)\) 开始跳跃,一次可以跳到右下方的任意一格,问跳到\((n,m)\) 的方案数。
分析
此题如果没有特殊条件跳到任意一格,就是很经典的组合问题:考虑从\((1,1)\) 走到\((n,m)\) 会经历\(n+m-2\) 次移动,其中\(C_{n+m-2}^{n-1}\) 次往下,就是方案数了。
但是此题不太一样可以跳跃,因此往下的次数不再是\(n-1\) 但还是尝试类似的方法:枚举到\((n,m)\)在行上走了\(x\) 步,在列上也走了\(x\) 步,那么两者的方案数乘积就是答案了,贡献为\(C_{n - 2}^x \cdot C_{m-2}^x\)
因此答案
\[ans = \sum C_{n-2}^x\cdot C_{m-2}^x = \sum C_{n-2}^x\cdot C_{m-2}^{m-2-x}= C_{n+m-4}^{m-2}
\]
最后一步又叫做范德蒙德卷积
\[\sum C_{n}^k\cdot C_{m}^{k-i}= C_{n + m}^{k}
\]
代码
ll fac[maxn], inv[maxn];
void init()
{
fac[0] = 1;
for (int i = 1; i < maxn; i++)
{
fac[i] = fac[i - 1] * i % MOD;
}
}
ll Cc(ll x, ll y)
{
return fac[x] * ksm(fac[y] * fac[x - y] % MOD, MOD - 2,MOD) % MOD;
}
int main() {
ll m, n;
init();
while (~scanf("%lld%lld", &n, &m)) {
if (m > n) swap(n, m);
Put(Cc(m + n - 4, n - 2));
puts("");
}
}