四边形不等式

四边形不等式

引入:

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

    $$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(N^3)\)

  

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

算法介绍:

  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)\) 取得最优值时对应的下标(即 \(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)$$

例题:

P4767 [IOI2000]邮局

#include<bits/stdc++.h>
using namespace std;
const int N=3e3+5,M=3e2+5;
int n,m,a[N],dp[N][M],w[N][N],d[N][M];
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    for(int l=1;l<=n;l++){
        w[l][l]=0; 
        for(int r=l+1;r<=n;r++) w[l][r]=w[l][r-1]+a[r]-a[l+r>>1];
    } 
    sort(a+1,a+n+1); memset(dp,0x3f3f3f3f,sizeof(dp)); dp[0][0]=0;
    for(int j=1;j<=m;j++){
        d[n+1][j]=n;
        for(int i=n;i>=1;i--){
            int minn=0x3f3f3f3f,minid;
            for(int k=d[i][j-1];k<=d[i+1][j];k++){
                if(dp[k][j-1]+w[k+1][i]<minn) minn=dp[k][j-1]+w[k+1][i],minid=k;}
            dp[i][j]=minn,d[i][j]=minid;
        }
    }
    cout<<dp[n][m]<<endl;
    system("pause");
    return 0;
}
posted @ 2021-08-10 20:45  Evitagen  阅读(175)  评论(0编辑  收藏  举报