LeetCode HOT100 - 不同路径

实际上比较合适的方法是 DP

因为这里又是一个计算方案数的问题,以及每次只会从上方或者左侧转移过来

不过这里第一时间想到的是组合数的解法

因为每次要向右移动以及向下移动的次数是固定的,相当于我们找这些移动的排列数,所以能想到答案是 \(\frac{(n + m - 2)!}{(n - 1)!(m - 1)!}\),也就是 \(C^{m - 1}_{n + m - 2}\)

关键就是怎么去计算,因为直接计算会溢出 long long

相对合理一些的方法是边乘边除(但是值比较大的时候感觉仍然是会溢出的,正常应该用 Mod ?)

这样做的前提是我们能够保证每次除的时候是整除

设 total = m + n - 2,我们要算的是 C(total, k)

第 i 步,ans = ans * (total - k + i) / i;

i = 0 时, ans = 1 = C(tot, 0)

假设进入第 i 步之前,ans = C(total, i-1)
那么

\[\begin{aligned} &ans * \frac{total - k + i}{i} \\ =\ &C(total, i-1) × \frac{total - i + 1}{i} \\ =\ &\frac{total!}{(i-1)! × (total-i+1)!} × \frac{total - i + 1}{i} \\ =\ &\frac{total!}{(i-1)! × (total-i)!} × \frac{1}{i} \\ =\ &\frac{total!}{i! × (total-i)!} \\ =\ &C(total, i) \end{aligned} \]

由归纳法可知,结果一定是整数

using i64 = long long;

class Solution {
public:
    int uniquePaths(int m, int n) {
        int total = m + n - 2;
        int k = min(m, n) - 1;
        i64 ans = 1;
        for (int i = 1; i <= k; ++i) {
            ans = ans * (total - k + i) / i;
        }
        return (int)ans;
    }
};
posted @ 2026-05-13 23:42  rdcamelot  阅读(17)  评论(0)    收藏  举报