• 石子合并 区间DP模板题


    题目链接:https://vjudge.net/problem/51Nod-1021

    题意

    N堆石子摆成一条线。现要将石子有次序地合并成一堆。规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的代价。计算将N堆石子合并成一堆的最小代价。

    例如:1 2 3 4 ,有不少合并方法

    1 2 3 4 => 3 3 4(3) => 6 4(9) => 10(19)
    1 2 3 4 => 1 5 4(5) => 1 9(14) => 10(24)
    1 2 3 4 => 1 2 7(7) => 3 7(10) => 10(20)
    

    括号里面为总代价可以看出,第一种方法的代价最低,现在给出n堆石子的数量,计算最小合并代价。

    输入

    第1行:N(2 <= N <= 100)
    第2 - N + 1:N堆石子的数量(1 <= A[i] <= 10000)

    输出

    输出最小合并代价

    样例输入

    4
    1
    2
    3
    4
    

    样例输出

    19
    

    题解:
    这道题目如果其实我自己接触的时候还是很早的,我很早很早之前就在一场比赛当中接触到了这道题目,那是很久很久之前的一个春天,我大一的时候的一场校赛中,我唯一没有做出来TLE的题,因为当时还不知道记忆化搜索这个概念。
    所以我当时的解法是用的dfs,没有使用记忆化进行剪枝。
    这里的记忆化搜索其实可以对应动态规划的状态转移方程。
    首先我们可以回到这道题目里面来,可以看到:
    区间 [1..N] 经过 N-1 次合并会获得最终的一个数,那么在经过 N-2 次合并的时候是会还剩2个数的,而且这两个数肯定还是连续的 a[i]a[i+1] ,所以,如果我们设 dp[i][j] 表示合并区间 [i,j] 的最小代价,那么:

    dp[i][j] = min(dp[i][k] + dp[k+1][j]) + sum(i,j) , 其中k=i,i+1,...,j-1
    

    这里的 sum(i,j) 表示 a[i]+a[i+1]+...+a[j]

    那么 dp[i][j] 怎么求呢,我们可以通过定义一个函数 dfs(i,j) 来求得,但是可以通过记忆化搜索进行剪枝优化,其实就是写DP的时候记录的一些中间结果对应的重叠子问题。

    代码如下(这个代码我没有验证过正确性,不过应该是没有问题的,主要理解他的思想):

    #include <iostream>
    using namespace std;
    
    const int maxn = 1010;
    
    int n, a[maxn], dp[maxn][maxn], sum[maxn];
    
    int dfs(int l, int r) {
        if (l == r) return 0;
        if (l+1 == r) {
            return dp[l][r] = a[l] + a[r];
        }
        if (dp[l][r])
            return dp[l][r];
        for (int i = l; i < r; i ++) {
            int tmp = dfs(l,i) + dfs(i+1, r) + sum[r] - sum[l-1];
            if (!dp[l][r]) dp[l][r] = tmp;
            else dp[l][r] = min(dp[l][r], tmp);
        }
        return dp[l][r];
    }
    
    int main() {
        cin >> n;
        for (int i = 1; i <= n; i ++) {
            cin >> a[i];
            sum[i] = sum[i-1] + a[i];
        }
        cout << dfs(1, n) << endl;
        return 0;
    }
    
  • 相关阅读:
    学习bn算法
    记录pytorch的几个问题
    Python: 你不知道的 super
    cmd里面怎么复制粘贴
    tensorflow的transpose
    应该做一个软件,直接把视频里面的英语,转换成字幕,然后翻译
    继续修改,爬虫贴吧,上次的每次只取一个图片.
    Deleting elements
    Map, filter and reduce
    List methods
  • 原文地址:https://www.cnblogs.com/zifeiy/p/10716703.html
Copyright © 2020-2023  润新知