动态规划5-区间动态规划(区间DP)

区间动态规划

开始学习动态规划进阶了,不过感觉这个难度有点超NOIP省赛的难度了。。。算了,反正都买了,还是学吧。。。

1.概述

区间 DP:是指在一段区间上进行的一系列动态规划。
对于区间 DP 这一类问题,我们需要计算区间[1,n] 的答案,通常用一个二维数组 dp表示,其中 dp[x][y] 表示区间 [x,y]。

2.一般套路

有些题目,dp[l][r] 由 dp[l][r−1] 与 dp[l+1][r] 推得;也有些题目,我们需要枚举区间 [l,r] 内的中间点,由两个子问题合并得到,也可以说 dp[l][r] 由 dp[l][k] 与 dp[k+1][r]dp[k+1][r]dp[k+1][r] 推得,其中 l≤k< r。
对于长度为 n 的区间 DP,我们可以先计算 [1,1],[2,2]…[n,n] 的答案,再计算 [1,2],[2,3]…[n−1,n],以此类推,直到得到原问题的答案。

3.下面给出枚举中间点的代码模版:

    for (int l=2;l<=n;l++){
        int en;
        for(int st=1;st<=n-l+1;st++){
            en=st+l-1;
            for(int k=st+1;k<en;k++){
                if(dp[st][k-1]*dp[k+1][en]+a[k]>dp[st][en]){
                    dp[st][en]=dp[st][k-1]*dp[k+1][en]+a[k];
                    root[st][en]=k;
                }
            }
            if(dp[st][en-1]+a[en]>dp[st][en]){
                    dp[st][en]=dp[st][en-1]+a[en];
                    root[st][en]=en;
            }
            if(dp[st+1][en]+a[st]>dp[st][en]){
                dp[st][en]=dp[st+1][en]+a[st];
                root[st][en] = st;
             }
          }
    }

值得注意的是:
1.必须先枚举区间长度l否则会炸。
2.注意枚举顺序为长度=>起始点=>中间点,起始点循环开始后马上算终止节点,边界的节点应该在枚举中间节点的循环之外进行!

猜你喜欢

转载自blog.csdn.net/Liukairui/article/details/80984539
今日推荐