区间DP+平行四边形优化分析

3 篇文章 0 订阅

区间DP模版:

for (int len = 1; len < n; len++) { //操作区间的长度
        for (int i = 0, j = len; j <= n; i++, j++) { //始末
            //检查是否匹配(非必须)
            for (int s = i; s < j; s++) {
                //update
            }
        }
    }

如果我们要得知一个大区间的情况,由于它必定是由从多个长度不一的小区间转移而来(转移情况未知),我们可以通过求得多个小区间的情况,从而合并信息,得到大区间。这样的算法复杂度为O(N^3)。

例:石子合并问题

#include <cstdio>
#define min(x, y) (x > y ? y : x)
#define INF 0x3f3f3f3f
using namespace std;

const int maxn = 210;
int dp[maxn][maxn];
int sum[maxn];
int a[maxn];

int main(int argc, const char * argv[]) {
    
    int n;
    while (~scanf("%d", &n)) {
        for (int i = 1; i <= n; i++) {
            scanf("%d", &a[i]);
            sum[i] = sum[i - 1] + a[i];
        }
        for (int len = 1; len < n; len++) { //操作区间的长度
            for (int i = 1, j = len + 1; j <= n; i++, j++) { //始末
                //检查是否匹配(非必须)
                dp[i][j] = INF;
                for (int s = i; s < j; s++) {
                    dp[i][j] = min(dp[i][j], dp[i][s] + dp[s + 1][j] + sum[j] - sum[i - 1]);
                }
            }
        }
        printf("%d\n", dp[1][n]);
    }
    return 0;
}

题目总结:https://www.cnblogs.com/123-123/p/5813327.html


平形四边形优化分析:

  在动态规划中,经常遇到形如下式的状态转移方程:

    m(i,j)=min{m(i,k-1),m(k,j)}+w(i,j)(i≤k≤j)(min也可以改为max)

  上述的m(i,j)表示区间[i,j]上的某个最优值。w(i,j)表示在转移时需要额外付出的代价。该方程的时间复杂度为O(N3)


  下面我们通过四边形不等式来优化上述方程,首先介绍什么是“区间包含的单调性”和“四边形不等式”

    1、区间包含的单调性:如果对于 i≤i'<j≤j',有 w(i',j)≤w(i,j'),那么说明w具有区间包含的单调性。(可以形象理解为如果小区间包含于大区间中,那么小区间的w值不超过大区间的w值)

    2、四边形不等式:如果对于 i≤i'<j≤j',有 w(i,j)+w(i',j')≤w(i',j)+w(i,j'),我们称函数w满足四边形不等式。(可以形象理解为两个交错区间的w的和不超过小区间与大区间的w的和)

 

  下面给出两个定理:

    1、如果上述的 w 函数同时满足区间包含单调性和四边形不等式性质,那么函数 m 也满足四边形不等式性质

       我们再定义 s(i,j) 表示 m(i,j) 取得最优值时对应的下标k(即 i≤k≤j 时,k 处的 w 值最大,则 s(i,j)=k)。此时有如下定理

    2、假如 m(i,j) 满足四边形不等式,那么 s(i,j) 单调,即 s(i,j)≤s(i,j+1)≤s(i+1,j+1)。

 

  好了,有了上述的两个定理后,我们发现如果w函数满足区间包含单调性和四边形不等式性质,那么有 s(i,j-1)≤s(i,j)≤s(i+1,j) 。

  即原来的状态转移方程可以改写为下式:

     m(i,j)=min{m(i,k-1),m(k,j)}+w(i,j)(s(i,j-1)≤k≤s(i+1,j))(min也可以改为max)

  由于这个状态转移方程枚举的是区间长度 L=j-i,而 s(i,j-1) 和 s(i+1,j) 的长度为 L-1,是之前已经计算过的,可以直接调用。

  不仅如此,区间的长度最多有n个,对于固定的长度 L,不同的状态也有 n 个,故时间复杂度为 O(N^2),而原来的时间复杂度为 O(N^3),实现了优化!

  今后只需要根据方程的形式以及 w 函数是否满足两条性质即可考虑使用四边形不等式来优化了。

例:石子合并

#include <cstdio>
#include <cstring>
#define N 1005
int s[N][N],f[N][N],sum[N],n;
int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        memset(f,127,sizeof(f));
        sum[0]=0;
        for(int i=1; i<=n; i++){
            scanf("%d",&sum[i]);
            sum[i]+=sum[i-1];
            f[i][i]=0;
            s[i][i+1]=i;
        }
        for(int i=1; i<=n; i++)
            f[i][i+1]=sum[i+1]-sum[i-1];

        for(int i=n-2; i>=1; i--)
            for(int j=i+2; j<=n; j++)
                for(int k=s[i][j-1]; k<=s[i+1][j]; k++)
                if(f[i][j]>f[i][k]+f[k+1][j]+sum[j]-sum[i-1])
                {
                    f[i][j]=f[i][k]+f[k+1][j]+sum[j]-sum[i-1];
                    s[i][j]=k;
                }
    
        printf("%d\n",f[1][n]);
    }
    return 0;
}

(btw,对于石子合并问题,如要求最大值,则不能采用平形四边形优化的方法,为什么我也没想清楚.....如果有人知道了可以在评论区告诉我
  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
区间DP四边形不等式优化是一种用于优化区间DP的方法。四边形不等式可以用来简化具有特定转移方式的DP问题。具体来说,如果转移方程满足区间包含单调性和四边形不等式,那么可以使用四边形不等式优化来减少计算量。 要判断一个转移方程是否满足区间包含单调性和四边形不等式,可以先进行表格计算来观察。如果观察到满足条件,就可以使用四边形不等式优化。 引理表明,如果一个转移方程满足区间包含单调性和四边形不等式,那么优化后的转移方程也会满足四边形不等式。这意味着通过四边形不等式优化可进一步减少计算复杂度。 因此,区间DP四边形不等式优化是一种有效的优化方法,可以提高算法的效率。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [【DP四边形不等式优化详解(一)](https://blog.csdn.net/qq_37656398/article/details/103537173)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [四边形不等式(优化区间DP技巧)](https://blog.csdn.net/AC__dream/article/details/123668489)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值