• POJ1160 Post Office-四边形不等式优化DP


    方程

    $Large f(i,j)=min(f(i-1,k)+w(k+1,j))$

    其中$w(i,j)$表示在$[i,j]$的村庄都去一个邮局的最小距离和

    证明w满足四边形不等式

    设$w_k(i,j)$表示$[i,j]$的村庄都去$k$村庄邮局的距离和

    对于$forall k$满足$w_k(i,j+1)=w(i,j+1)$都有$w_k(i+1,j)=w(i+1,j)$

    (因为k只有选$i,j$的中间位置$w(i,j)$才是最小的)

    $w(i,j)+w(i+1,j+1)le w_k(i,j)+w_k(i+1,j+1)=w(i,j+1)+w(i+1,j)$

    证明f满足四边形不等式

    设$f_k(i,j)=f(i-1,k-1)+w(k,j)$

    对于$forall ile i^{'}le jle j^{'}$,设$k=s(i,j^{'}),t=s(i^{'},j)$

    1.如果$kle t$

    有$f(i,j)+f(i^{'},j^{'})le f_k(i,j)+f_t(i^{'},j^{'})= f(i-1,k-1)+w(k,j)+f(i^{'}-1,t-1)+w(t,j^{'})$

    因为w满足四边形不等式$f(i,j)+f(i^{'},j^{'})le f(i-1,k-1)+w(k,j^{'})+f(i^{'}-1,t-1)+w(t,j)$

    即$f(i,j)+f(i^{'},j^{'})le f(i,j^{'})+f(i^{'},j)$

    2.如果$kgt t$

    则只需证$f(i-1,t-1)+w(t,j)+f(i^{'}-1,k-1)+w(k,j^{'})le f(i-1,k-1)+w(k,j^{'})+f(i^{'}-1,t-1)+w(t,j)$

    设$k_1=s(i-1,k-1),k_2=s(i-2,k_1-1)……k_n=s(i-n,k_{n-1}-1)$

    $t_1=s(i^{'}-1,t-1),t_2=s(i^{'}-2,t_1-1)……t_n=s(i^{'}-n,t_{n-1}-1)$

    如果$k_1le t_1$,就可以用上面的证明方法证出来

    否则,递归本次证明直到得到求证$f(1,t_n-1)+f(i_{'}-i+1,k_n-1)le f(1,k_n-1)+f(i_{'}-i+1,t_n-1)$

    化简得$w(1,t_n-1)+f(i_{'}-i,t_{n+1}-1)+w(t_{n+1},k_n-1)le w(1,k_n-1)+f(i_{'}-i,t_{n+1}-1)+w(t_{n+1},t_n-1)$

    由w满足四边形不等式得$w(1,t_n-1)+w(t_{n+1},k_n-1)le w(1,k_n-1)+w(t_{n+1},t_n-1)$

    所以$f(i,j)+f(i^{'},j^{'})le f(i,j^{'})+f(i^{'},j)$

    证明$f(i,j)$的决策$s(i,j)$是单调的

    1.设$k=s(i,j)$,对于所有$tle k$

    有$w(t,j)+w(k,j+1)le w(t,j+1)+w(k,j)$

    两边同时加上$f(i,t-1)+f(i,k-1)$得$f_t(i,j)+f_k(i,j+1)le f_k(i,j)+f_t(i,j+1)$

    因为$f_t(i,j)ge f_k(i,j)$,所以$f_k(i,j+1)le f_t(i,j+1)$

    所以$s(i,j)le s(i,j+1)$

    2.设$k=s(i,j)$,对于所有$tle k$

    有$f(i,t-1)+f(i+1,k-1)le f(i+1,t-1)+f(i,k-1)$

    两边同时加上$w(t,j)+w(k,j)$得$f_t(i,j)+f_k(i+1,j)le f_k(i,j)+f_t(i+1,j)$

    因为$f_t(i,j)ge f_k(i,j)$,所以$f_k(i+1,jle f_t(i+1,j)$

    所以$s(i,j)le s(i+1,j)$

    代码

    #include<cstdio>
    #include<cstring>
    using namespace std;
    #define maxn 305
    #define maxp 40
    int f[maxp][maxn],s[maxp][maxn],w[maxn][maxn],a[maxn];
    int main(){
        memset(f,0x3f,sizeof(f));
        int n,p;scanf("%d%d",&n,&p);
        for(int i=1;i<=n;i++)scanf("%d",a+i);
        for(int i=1;i<=n;i++){
            for(int j=i+1;j<=n;j++){
                w[i][j]=w[i][j-1]+a[j]-a[(i+j)/2];
            }
            s[0][i]=1;
        }
        f[0][0]=0;
        for(int i=1;i<=p;i++){
            f[i][i]=0;s[i][i]=i;s[i][n+1]=n;
            for(int j=n;j>i;j--){
                for(int k=s[i-1][j];k<=s[i][j+1];k++){
                    if(f[i][j]>f[i-1][k-1]+w[k][j]){
                        f[i][j]=f[i-1][k-1]+w[k][j];s[i][j]=k;
                    }
                }
            }
        }
        printf("%d",f[p][n]);
        return 0;
    } 
  • 相关阅读:
    MySQL锁总结
    DDL和DML
    字节、字、位、比特之间的关系
    Mysql数据库、表设计规范指南
    Mysql性能优化关键配置指南
    3.python正则匹配不到内容时消耗大量内存
    1. postman使用
    2. python提示:TypeError: unhashable type: 'list'
    14. selenium的Page Object模型
    12.unittest的学习
  • 原文地址:https://www.cnblogs.com/bennettz/p/8987660.html
Copyright © 2020-2023  润新知