四边形不等式简析

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/A1847225889/article/details/81489480

并不是很透彻,只是切掉了一道模板题。
[TOC]

四边形不等式

不等式
w ( i , j ) ,对于 a b c d ,满足

w ( a , c ) + w ( b , d ) w ( a , d ) + w ( b , c )

那么就称它满足四边形不等式。

区间包含单调性

w ( i , j ) ,对于 a b c d ,满足

w ( b , c ) w ( a , d )

那么就称它满足区间包含单调性。

各种定理

定理一

如果有DP式

f ( i , j ) = min f ( i , k ) + f ( k + 1 , j ) + w ( i , j ) ( f ( i , i ) = 0 )

如果 w ( i , j ) 满足四边形不等式和区间包含单调性。
那么 f ( i , j ) 也满足四边形不等式和区间包含单调性。

定理二

设满足四边形不等式的 f ( i , j ) 的决策点为 s ( i , j ) ,则

s ( i , j 1 ) s ( i , j ) s ( i + 1 , j )

定理三

如果 w ( i , j ) 满足四边形不等式,当且仅当

w ( i , j ) + w ( i + 1 , j + 1 ) w ( i + 1 , j ) + w ( i , j + 1 )


以上就是主要的内容。
证明?上网查,或自己推,我懒得打了。(一般只要能够自己推出来就能够理解了)

模板

例题(模板):HDU3506 Monkey Party

using namespace std;
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <climits>
int n,nn;
int a[2001],sum[2001];
int f[2001][2001];
int s[2001][2001];
int main()
{
    while (scanf("%d",&n)!=EOF)
    {
        for (int i=1;i<=n;++i)
            scanf("%d",&a[i]);
        memcpy(a+n+1,a+1,sizeof(int)*n);
        nn=n<<1;
        for (int i=1;i<=nn;++i)
            sum[i]=sum[i-1]+a[i];
        memset(f,127,sizeof f);
        for (int i=1;i<=nn;++i)
            f[i][i]=0,s[i][i]=i;
    //以下注销掉的部分是没有用四边形不等式的方法
    //  for (int len=1;len<n;++len)
    //      for (int i=1;i+len<=nn;++i)
    //      {
    //          int j=i+len;
    //          for (int k=i;k<j;++k)
    //              f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]+sum[j]-sum[i-1]);
    //      }
        for (int len=1;len<n;++len)
            for (int i=1;i+len<=nn;++i)
            {
                int j=i+len;
                for (int k=s[i][j-1];k<=s[i+1][j];++k)
                {
                    int newvalue=f[i][k]+f[k+1][j]+sum[j]-sum[i-1];
                    if (newvalue<f[i][j])
                    {
                        f[i][j]=newvalue;
                        s[i][j]=k;
                    }
                }
            }
        int ans=INT_MAX;
        for (int i=1;i<=n;++i)
            ans=min(ans,f[i][i+n-1]);
        printf("%d\n",ans);
    }
    return 0;
}

总结

一般情况下,四边形不等式用来优化区间DP,将时间复杂度硬生生地降一个维。(可能光是看程序看不出来,事实上,每一轮的处理,可以计算一下内部循环的次数,你将会惊奇的发现那是 O ( n ) 的)
有时候,四边形不等式不只是优化区间DP,这样的题还没打过,如果打过了就再补充。

猜你喜欢

转载自blog.csdn.net/A1847225889/article/details/81489480