四边形不等式

如果对于任意的a1≤a2< b1≤b2,有m[a1,b1]+m[a2,b2]≤m[a1,b2]+m[a2,b1],那么m[i,j]满足四边形不等式。

所以这是一个求(xuan)骗(xue)的东西。



定理

对方程

m(i,j)=min{m(i,k1),m(k,j)}+w(i,j)(ikj)

且s(i,j)表示m(i,j)取得最优值时对应的下标,有:

  • 区间包含的单调性:如果对于i≤i’< j≤j’,有w(i’,j)≤w(i,j’),那么说明w具有区间包含的单调性。
    区间包含的单调性
  • 四边形不等式:如果对于i≤i’< j≤j’,有w(i,j)+w(i’,j’)≤w(i’,j)+w(i,j’),我们称函数w满足四边形不等式。
    四边形不等式
    蓝线长和≤红线长和
  • 定理一:如果上述的w函数同时满足区间包含单调性和四边形不等式性质,那么函数m也满足四边形不等式性质。

  • 定理二:假如m(i,j)满足四边形不等式,那么s(i,j)单调,即s(i,j)≤s(i,j+1)≤s(i+1,j+1)。

然后k的范围就从 [ i , j ] 变成了[ s(i,j-1) , s(i+1,j) ],像这样:
表
m[1,3]取s[1,2]和s[2,3],
m[2,5]取s[ 2,4]=3,s[3,5]=3,相当于直接取3。
(然后记s[2,5]=3)
少了一重循环!!!

完美解释了OBST问题!!!
(其实就是套定理)

题目

NOI 1995 石子合并
(洛谷 P1880)
n<=100……如果n<=1000呢?
100的 O(n3) 还能过,1000的就得 O(n2) 了。

环形的……也不惧……
但最大值不单调,不能用四边形不等式
不过最大值可以两个端点的最大者取得。
最大值不单调
详解

题解 by myself

#include<iostream>
#include<cstdio>
using namespace std;
int a[2005],sum[2005];
int fmi[2005][2005],fma[2005][2005],
    smi[2005][2005];

int main(){
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        a[i+n]=a[i];
        sum[i]=sum[i-1]+a[i];
        smi[i][i]=i;
        }
    for(int i=1+n;i<=(n<<1);i++){
        sum[i]=sum[i-1]+a[i];
        smi[i][i]=i;
        }
    for(int i=(n<<1)-1;i;i--)
        for(int j=i+1;j<=(n<<1);j++){
            int jc=0,tmp=0x3f3f3f3f;
            fma[i][j]=max(fma[i][j-1],fma[i+1][j])+sum[j]-sum[i-1];
            /*注意这句,
              求最大值不能用四边形不等式,
              因为最大值不满足单调性,
              但最大值有一个性质,
              即总是在两个端点的最大者中取到。
            */
            for(int k=smi[i][j-1];k<=smi[i+1][j];k++){
                int tt=fmi[i][k]+fmi[k+1][j]+(sum[j]-sum[i-1]);
                if(tt<tmp){
                    tmp=tt;
                    jc=k;
                    }
                }
            smi[i][j]=jc;
            fmi[i][j]=tmp;
            }
    int ama=0,ami=0x3f3f3f3f;
    for(int i=1;i<=n;i++){
        ama=max(ama,fma[i][i+n-1]);
        ami=min(ami,fmi[i][i+n-1]);
        }
    printf("%d\n%d",ami,ama);

    return 0;
    }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值