1 条题解

  • 0
    @ 2026-3-24 9:41:14

    文字教学

    这道题的核心问题是直接递归会导致大量重复计算,因此必须使用记忆化搜索(Memoization)来优化。我们将已经计算过的结果存储在一个三维数组中,避免重复计算。

    关键要点:

    1. 由于当 a,b,ca, b, c 超过 20 时都按 20 处理,我们只需要计算 0a,b,c200 \leq a, b, c \leq 20 的情况。
    2. 条件判断的优先级很重要:先检查是否有参数 0\leq 0,再检查是否有参数 >20> 20
    3. 使用一个三维数组 f[21][21][21] 存储已计算的结果,初始化为 -1 表示未计算。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    ll f[21][21][21];
    
    ll w(ll a, ll b, ll c) {
        if (a <= 0 || b <= 0 || c <= 0) return 1;
        if (a > 20 || b > 20 || c > 20) return w(20, 20, 20);
        if (f[a][b][c] != -1) return f[a][b][c];
        if (a < b && b < c) {
            f[a][b][c] = w(a, b, c-1) + w(a, b-1, c-1) - w(a, b-1, c);
        } else {
            f[a][b][c] = w(a-1, b, c) + w(a-1, b-1, c) + w(a-1, b, c-1) - w(a-1, b-1, c-1);
        }
        return f[a][b][c];
    }
    
    int main() {
        memset(f, -1, sizeof(f));
        ll a, b, c;
        while (cin >> a >> b >> c) {
            if (a == -1 && b == -1 && c == -1) break;
            cout << "w(" << a << ", " << b << ", " << c << ") = " << w(a, b, c) << endl;
        }
        return 0;
    }
    
    • 1

    信息

    ID
    456
    时间
    1000ms
    内存
    125MiB
    难度
    3
    标签
    递交数
    8
    已通过
    3
    上传者