1 条题解

  • 0
    @ 2023-1-7 16:53:29

    递推

    #include <bits/stdc++.h>
    #define int long long
    using namespace std;
    int n;
    int a[105];
    int sum[105];     // sum[i]: a[1]~a[i] 之和
    int dp[105][105]; // dp[i][j] 表示 a[i]~a[j] 合并成一堆的最小消耗
    signed main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        cin >> n;
        for (int i = 1; i <= n; i++)
            cin >> a[i];
        // sum
        for (int i = 1; i <= n; i++)
            sum[i] = sum[i - 1] + a[i];
        // dp
        memset(dp, 0x3f, sizeof(dp));
        for (int len = 1; len <= n; len++)
            for (int l = 1; l + len - 1 <= n; l++)
            {
                int r = l + len - 1;
                // 计算dp[l][r]
                if (len == 1)
                {
                    dp[l][r] = 0;
                    continue;
                }
                for (int k = l; k < r; k++) // 讨论区间划分点
                {
                    // 当前的方案:
                    // 先把 a[l]~a[k] 合并成一堆 : 最少消耗 dp[l][k]
                    // 再把 a[k+1]~a[r] 合并成一堆 : 最少消耗 dp[k+1][r]
                    // 最后把这两堆合并在一起
                    dp[l][r] = min(dp[l][r],
                                   dp[l][k] + dp[k + 1][r] + (sum[r] - sum[l - 1]));
                }
            }
        cout << dp[1][n] << "\n";
        return 0;
    }
    

    记忆化搜索

    #include <bits/stdc++.h>
    #define int long long
    using namespace std;
    int n;
    int a[105];
    int sum[105];     // sum[i]: a[1]~a[i] 之和
    int dp[105][105]; // dp[i][j] 表示 a[i]~a[j] 合并成一堆的最小消耗
    // 返回 a[i]~a[j] 合并成一堆的最小消耗
    int dfs(int l, int r)
    {
        if (dp[l][r] != -1)
            return dp[l][r];
        if (l == r)
            return dp[l][r] = 0;
        dp[l][r] = 0x3f3f3f3f3f3f3f3fLL;
        for (int k = l; k <= r - 1; k++) // 分界点
            dp[l][r] = min(dp[l][r],
                           dfs(l, k) + dfs(k + 1, r) + sum[r] - sum[l - 1]);
        return dp[l][r];
    }
    signed main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        cin >> n;
        for (int i = 1; i <= n; i++)
            cin >> a[i];
        // sum
        for (int i = 1; i <= n; i++)
            sum[i] = sum[i - 1] + a[i];
        // dp
        memset(dp, -1, sizeof(dp));
        cout << dfs(1, n) << "\n";
        return 0;
    }
    
    • 1

    信息

    ID
    493
    时间
    1000ms
    内存
    128MiB
    难度
    5
    标签
    (无)
    递交数
    72
    已通过
    30
    上传者