码迷,mamicode.com
首页 > 其他好文 > 详细

POJ1160

时间:2014-08-02 04:00:12      阅读:178      评论:0      收藏:0      [点我收藏+]

标签:style   blog   color   使用   io   for   div   算法   

再次使用强大的四边形优化dp

f[i][j]=max(f[k][j-1]+w[k+1][i])

  其中f[i][j]表示前i个村落有j个邮电局,w[i][j]表示[i,j]区间上安装一个邮电局最短路径和

其中w[i][j]邮电局必然是安装在(i+j)/2(中位数)的村落中,若(i+j)/2不为整数,则中间两个村落都可以。证明可以看《算法导论》

至于四边形不等式,这次,可以直接容易得到 s[i][j-1]<=s[i][j]<=s[i+1][j] 稍微证明下就可以出来,凭感觉都是对的。

 

#include <cstdio>
#include <cstring>
#define min(x,y) (x>y?y:x)
int v,p,a[305],sum[305],w[305][305],f[305][35],s[305][35];
int main()
{
    memset(f,127,sizeof(f));
    scanf("%d%d",&v,&p);
    for(int i=1; i<=v; i++){
        scanf("%d",&a[i]);
        sum[i]=a[i]+sum[i-1];
    }
    for(int i=1; i<=v; i++){
        w[i][i]=0;
        for(int j=i+1; j<=v; j++){
            w[i][j]=sum[j]-sum[(i+j)/2]-sum[(i+j)/2-1]+sum[i-1];
            if((i+j)%2!=0) w[i][j]-=a[(i+j)/2];
        }
    }
    for(int i=1; i<=v; i++)
        f[i][1]=w[1][i];
    for(int j=2; j<=p; j++){
        s[v+1][j]=v-1;
        for(int i=v; i>=j; i--)
        {
            for(int k=s[i][j-1]; k<=s[i+1][j]; k++)
            if(f[i][j]>f[k][j-1]+w[k+1][i])
            {
                f[i][j]=f[k][j-1]+w[k+1][i];
                s[i][j]=k;
            }
        }
    }
    printf("%d",f[v][p]);
    return 0;
}

 

POJ1160,布布扣,bubuko.com

POJ1160

标签:style   blog   color   使用   io   for   div   算法   

原文地址:http://www.cnblogs.com/Mathics/p/3886105.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!