• 「题解」洛谷 P1063 能量项链


    题目

    P1063 能量项链

    简化题意

    给你一个环,环上每个点有点权,每次能合并两个相邻的点,得到的贡献是两点点权的乘积再乘上靠后的点的下一个点的点权,合并出来的新点的点权是靠前的点的点权。问你最大贡献是多少。

    题解

    区间 dp。

    (a_i) 表示点 (i) 的点权。

    (f_{i,j}) 表示合并了 ([i,j]) 所能得到的最大贡献。

    状态转移方程如下:

    (f_{i,j} = max(f_{i,j},f_{i,k} + f_{k + 1,j} + a[i] * a[k + 1] * a[j + 1]))

    表示合并 ([i,j]) 这个区间是先合并了 ([i,k])([k + 1,j])这两个区间然后进行的合并。

    Code

    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <iostream>
    #include <algorithm>
    #define M 201
    
    int max(int a, int b) { return a > b ? a : b; }
    
    int n, a[M], b[M], f[M][M];
    
    int main() {
        scanf("%d", &n);
        for (int i = 1; i <= n; ++i) {
            scanf("%d", &a[i]);
            a[n + i]  = a[i];
        }
        for (int i = 1; i <= 2 * n; ++i) b[i] = a[i % n + 1];
        memset(f, 0, sizeof f);
        for (int l = 1; l <= n; ++l) {
            for (int i = 1; i + l - 1 <= 2 * n; ++i) {
                int j = i + l - 1;
                for (int k = i; k < j; ++k) {
                    f[i][j] = max(f[i][j], f[i][k] + f[k + 1][j] + a[i] * b[k] * b[j]);
                }
            }
        }
        int ans = 0;
        for (int i = 1; i <= n; ++i) {
            ans = max(ans, f[i][i + n - 1]);
        }
        std::cout << ans << '
    ';
        return 0;
    }
    
  • 相关阅读:
    Tushare模块
    关于上下文
    Flask的session使用
    Flask的请求处理机制
    Tomcat启动报错:SERVER: Error ListenerStart 排查过程记录
    Extjs中设置只读的样式问题
    Extjs中获取getEl获取undefined的问题
    【转载】使用SoapUI 测试Web Service
    PLSQL快捷键设置
    PLSQL配置数据库的方式
  • 原文地址:https://www.cnblogs.com/poi-bolg-poi/p/13662094.html
Copyright © 2020-2023  润新知