Loading

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("");
    }
}
posted @ 2020-08-28 10:17  MQFLLY  阅读(97)  评论(0编辑  收藏  举报