zoukankan      html  css  js  c++  java
  • 区间DP学习 LibreOJ-10147 石子合并

    区间DP是线性DP的一种,它以“区间长度”作为DP的“阶段”,使两个坐标(区间的左右端点)描述每个维度。

    区间DP中,一个状态由若干个比它更小且包含于它的区间所代表的状态转移而来。区间DP的初态一般就由长度为1的“元区间”组成。这种向下划分,再向上递推的模式与某些树形结构如线段树有很大的相似之处。

    石子合并

    若第l堆和第r堆被合并,说明l-r之间的每堆石子都已经合并,这样l,r才可能相邻。因此任意一堆石子均可以用一个闭区间[l , r] 来描述。

    动态规划中,就意味着两个长度较小的区间上的信息向一个更长的区间发生了转移,划分点k就是转移的决策点。 因此把区间长度len作为DP的阶段。

    编程实现动态规划状体转移方程时,务必分清 阶段 , 状态与决策,三者应该从外到内的顺序一次循环。

    int s[205];
    int f1[205][205];
    int f2[205][205];
    int num[305];
    int n;
    
    inline int d(int i, int j) {
        return s[j] - s[i - 1];
    }
    
    int main() {
        scanf("%d", &n);
        for (int i = 1; i <= n + n; i++) {
            if(i <= n) scanf("%d", &num[i]);
            num[i + n] = num[i];
            s[i] = s[i - 1] + num[i];
        }
        for (int p = 1; p < n; p++) {
            for (int i = 1, j = i + p; (j < n + n) && (i < n + n);i++, j = i + p) {
                f2[i][j] = INF;
                for (int k = i; k < j; k++) {
                    f1[i][j] = max(f1[i][j], f1[i][k] + f1[k + 1][j] + d(i, j));
                    f2[i][j] = min(f2[i][j], f2[i][k] + f2[k + 1][j] + d(i, j));
                }
            }
        }
        int Max = -1;
        int Min = INF;
        for (int i = 1; i <= n; i++) {
            Max = max(Max, f1[i][i + n - 1]);
            Min = min(Min, f2[i][i + n - 1]);
        }
        printf("%d
    %d", Min, Max);
    }
  • 相关阅读:
    oracle语法
    cin.clear()、cin.sync()
    Intellij Idea Spring Boot 热部署
    navicat_premium_x64最新版安装说明
    激活navicat premium12
    时间戳Unix和时间之间的转换
    排序算法-- 大总结
    The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path
    final
    static
  • 原文地址:https://www.cnblogs.com/hznumqf/p/13416322.html
Copyright © 2011-2022 走看看