zoukankan      html  css  js  c++  java
  • 四边形不等式简析

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

    四边形不等式

    不等式
    w(i,j),对于abcd,满足

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

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

    区间包含单调性

    w(i,j),对于abcd,满足

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

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

    各种定理

    定理一

    如果有DP式

    f(i,j)=minf(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,j1)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
    ",ans);
        }
        return 0;
    }

    总结

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

  • 相关阅读:
    关于sizeof,对空指针sizeof(*p)可以吗?
    Mysql之锁(一)
    Mysql之事务
    Mysql之Explain关键字及常见的优化手段
    Mysql查询优化器之关于子查询的优化
    Mysql查询优化器之关于JOIN的优化
    Mysql查询优化器之基本优化
    Mysql之B+树索引实战
    Mysql之索引
    Mysql之InnoDB行格式、数据页结构
  • 原文地址:https://www.cnblogs.com/jz-597/p/11145283.html
Copyright © 2011-2022 走看看