• [P1388] 算式


    Description

    给出 (n le 15) 个数字,不改变它们的相对位置,在中间加入 (k) 个乘号和 ((n-k-1)) 个加号,括号随便加,使最终结果尽量大。

    Solution

    说好不写题解了的老龄选手怎么又来灌水?突然被人甩了个题,难顶

    网上有大量题解都假设了,最优解一定可以表示为若干段和的乘积,但在有 0 存在的情况下显然存在反例

    解决方案是,放弃这个假设,但是最优子结构仍然可以使用

    仍然用 (f[i][j][k]) 表示区间 ([i,j]) 中添加了 (k) 个乘号的方案数

    转移时分别考虑用加号连接和乘号连接的情况即可

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    
    const int N = 1e2 + 5;
    int n, K;
    int a[N];
    int f[N][N][N];
    
    signed main()
    {
        cin >> n >> K;
        for (int i = 0; i < n; i++)
            cin >> a[i];
        memset(f, -1, sizeof f);
        for (int i = 0; i < n; i++)
            for (int j = i; j < n; j++)
                f[i][j][0] = a[j] + (j > i) * f[i][j - 1][0];
        for (int l = 0; l < n; l++)
            for (int i = 0, j = i + l; j < n; i++, j++)
                for (int k = 0; k <= K; k++)
                    for (int m = i; m < j; m++)
                        for (int x = 0; x <= k; x++)
                        {
                            if (~f[i][m][x] && ~f[m + 1][j][k - x])
                                f[i][j][k] = max(f[i][j][k], f[i][m][x] + f[m + 1][j][k - x]);
                            if (x < k)
                                if (~f[i][m][x] && ~f[m + 1][j][k - x - 1])
                                    f[i][j][k] = max(f[i][j][k], f[i][m][x] * f[m + 1][j][k - x - 1]);
                        }
        cout << f[0][n - 1][K] << endl;
    }
    
  • 相关阅读:
    第36课 经典问题解析三
    第35课 函数对象分析
    67. Add Binary
    66. Plus One
    58. Length of Last Word
    53. Maximum Subarray
    38. Count and Say
    35. Search Insert Position
    28. Implement strStr()
    27. Remove Element
  • 原文地址:https://www.cnblogs.com/mollnn/p/14721696.html
Copyright © 2020-2023  润新知