zoukankan      html  css  js  c++  java
  • 「题解」洛谷 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;
    }
    
  • 相关阅读:
    vue-router 滚动行为封装示例
    HTML5 History 模式 后端ngnix配置
    vue-router 嵌套命名视图
    npm 源管理 nrm
    windows系统git使用zip命令报错解决方法
    vue v-html 动态内容样式无效解决方法
    vue 项目打包 本地预览
    Vue 项目环境变量
    Oracle中的统计信息
    宽表和窄表的区别---字段
  • 原文地址:https://www.cnblogs.com/poi-bolg-poi/p/13662094.html
Copyright © 2011-2022 走看看