1 条题解

  • 0
    @ 2025-5-6 12:50:31

    本题是多组输入的组合数计算问题,解题思路如下:

    1. 输入处理:持续读取 (N) 和 (M),遇 0 0 结束。
    2. 组合数计算
      • 利用 num 数组记忆化搜索,避免重复计算。 利用(C_{n}^m = C_{n}^{n - m})减少计算量。 按(C_{a}^i = C_{a}^{i - 1} \cdot \frac{a - i + 1}{i})递推计算 。
    3. 输出结果:按指定格式输出每组的组合数结果。
    #include <iostream>
    #include <cstring>
    #define ll long long
    using namespace std;
    
    ll n, m, num[105][105];
    
    // 更简洁的 gcd 函数实现
    ll gcd(ll a, ll b) {
        return b == 0 ? a : gcd(b, a % b);
    }
    
    ll query(ll a, ll b) {
        if (num[a][b] > 0)
            return num[a][b];
    
        if (b > a - b) b = a - b; // 优化计算,因为 C(a, b) = C(a, a - b)
    
        num[a][0] = 1;
        for (ll i = 1; i <= b; i++) {
            num[a][i] = num[a][i - 1] * (a - i + 1) / i;
        }
        return num[a][b];
    }
    
    int main() {
        memset(num, 0, sizeof(num));
        while (cin >> n >> m && (n || m)) {
            cout << n << " things taken " << m << " at a time is " << query(n, m) << " exactly." << endl;
        }
        return 0;
    }    
    
    • 1

    信息

    ID
    307
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    2
    已通过
    1
    上传者