• POJ-1160 Post Office (DP+四边形不等式优化)


    题目大意:有v个村庄成直线排列,要建设p个邮局,为了使每一个村庄到离它最近的邮局的距离之和最小,应该怎样分配邮局的建设,输出最小距离和。

    题目分析:定义状态dp(i,j)表示建设 i 个邮局最远覆盖到第 j 个村庄时最小距离和。容易得到dp(i,j)=min(dp(i-1,k-1)+w(k,j)),其中w(k,j)表示在k~j之间建设一个邮局的最小距离,所以很显然w(i,j)关于包含关系单调,可以看出w(i,j)还满足凸四边形不等式,所以dp(i,j)也满足凸四边形不等式。那么就有K(i,j-1)<=K(i,j)<=K(i+1,j),也就能通过限定k的取值范围达到优化的效果。其实这道题数据规模不大,不加优化也能AC。

    代码如下:

    # include<iostream>
    # include<cstdio>
    # include<cstring>
    # include<algorithm>
    using namespace std;
    
    const int INF=1<<30;
    
    int v,p;
    int dp[305][305];
    int K[305][305];
    int x[305],s[305];
    
    void read()
    {
        s[0]=0;
        for(int i=1;i<=v;++i){
            scanf("%d",x+i);
            s[i]=x[i]+s[i-1];
        }
    }
    
    int getw(int a,int b)
    {
        int m=(a+b)>>1;
        return s[b]-s[m]-x[m]*(a+b-2*m)-s[m-1]+s[a-1];
    }
    
    void solve()
    {
        for(int i=1;i<=v;++i){
            dp[i][i]=0;
            dp[0][i]=INF;
            K[i][i]=i;
        }
        for(int l=2;l<=v-p+1;++l){
            for(int i=1;i+l-1<=v;++i){
                int j=i+l-1;
                dp[i][j]=INF;
                int temp;
                for(int k=K[i][j-1];k<=K[i+1][j];++k){
                    if(dp[i][j]>(temp=dp[i-1][k-1]+getw(k,j))){
                        dp[i][j]=temp;
                        K[i][j]=k;
                    }
                }
            }
        }
        printf("%d
    ",dp[p][v]);
    }
    
    int main()
    {
        while(~scanf("%d%d",&v,&p))
        {
            read();
            solve();
        }
        return 0;
    }
    

      

  • 相关阅读:
    Cookie天使还是恶魔?
    Nhibernate学习起步之manytoone篇
    共享终结者ShareKiller
    基于弹性碰撞原理的抖动式窗口
    Nhibernate分析之华山论剑篇
    Nhibernate学习之manytomany篇
    JavaScript常用字符串函数
    让全中国人蒙羞的搜索爬虫
    近期项目的一些代码总结
    Nhibernate学习之性能改善1
  • 原文地址:https://www.cnblogs.com/20143605--pcx/p/5289538.html
Copyright © 2020-2023  润新知