【四边形】POJ 1160 Post Office

通道

题意:用数轴描述一条高速公路,有N个村庄,每一个村庄坐落在数轴的某个点上,需要选择P个村庄在其中建立邮局,要求每个村庄到最近邮局的距离和最小

思路:用f[i][j]表示建好i个邮局时覆盖到第j个村庄的最优解,那么就可以得到f[i][j]=min{f[i-1][k]+w[k+1][j]}(k<j),其中w[x][y]表示建一个邮局覆盖x到y的村庄的距离和

代码:

#include<stdio.h>
#include<string.h>
#define MAXD 310
#define MAXP 40
#define INF 0x3f3f3f3f
int N, P, f[MAXD][MAXD], A[MAXD], a[MAXD], K[MAXD][MAXD];
void init(){
    int i, j, k;
    A[0] = 0;
    for(i = 1; i <= N; i ++){
        scanf("%d", &a[i]);
        A[i] = A[i - 1] + a[i];
    }
}
int getw(int x, int y) {
    int t = (x + y) / 2;
    return A[y] - A[t] - (y - t) * a[t] - (A[t - 1] - A[x - 1] - (t - x) * a[t]);
}
void solve() {
    int i, j, k, p, t;
    for(i = 0; i <= N; i ++) {
        f[i][i] = 0;
        K[i][i] = i;
    }
    for(p = 1; p <= N - P; p ++) {
        for(i = 0; (j = i + p) <= N; i ++)
            f[i][j] = INF;
        for(i = 1; (j = i + p) <= N; i ++) {
            for(k = K[i][j - 1]; k <= K[i + 1][j]; k ++)
                if((t = f[i - 1][k - 1] + getw(k, j)) < f[i][j])  {
                    f[i][j] = t;
                    K[i][j] = k;
                }
        }
    }
    printf("%d\n", f[P][N]);
}
int main(){
    while(scanf("%d%d", &N, &P) == 2) {
        init();
        solve();
    }
    return 0;
}
View Code

 

posted @ 2015-08-02 16:28  mithrilhan  阅读(154)  评论(0编辑  收藏  举报