• [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;
    }
    
  • 相关阅读:
    Python 正则表达式(分组)
    django 笔记
    Java代理和动态代理机制分析和应用
    Chrome浏览器如何调试移动端网页信息
    【数据分析】Excle中安装数据分析工具
    【BigData】Java基础_socket编程中使用多线程
    【BigData】Java基础_多线程
    【BigData】Java基础_socket编程
    财务报表之利润表
    资产负债表的会计恒等式
  • 原文地址:https://www.cnblogs.com/mollnn/p/14721696.html
Copyright © 2020-2023  润新知