• POJ 1160 Post Office


     POJ_1160

        我们可以用f[i][j]表示建好i个邮局时覆盖到第j个村庄的最优解,那么就可以得到f[i][j]=min{f[i-1][k]+w[k+1][j]}(k<j),其中w[x][y]表示建一个邮局覆盖x到y的村庄的距离和,w[x][y]可以事先预处理出来。

        这个题目还可以用四边形不等式去优化,实际上四边形不等式优化难点不在于应用,只是在K[i][j-1]<=k<=K[i+1][j]中去选择更新f[i][j]的k即可,比较复杂的部分就在于对k可以这样选择做出证明。

        一般四边形不等式的证明步骤如下:

        ①证明w为凸,这一步用黑书上的定理w为凸当且仅当w[i][j]+w[i+1][j+1]<=w[i][j+1]+w[i+1][j],这样只要说明w[i+1][j]-w[i][j]是关于j单调递减的即可。

        ②证明f为凸,这一步要利用①中的定理去证f[i][j]+f[i+1][j+1]<=f[i][j+1]+f[i+1][j],而证明的方法通常是利用w为凸的结论,先假设f[i][j+1]取得最优解是k为x,f[i+1][j]取得最优解时f[i+1][j]为y,然后分x<y和y<x两种情况,将f[i][j]和f[i+1][j+1]各按k=x或k=y拆开之后,将拆出的w应用四边形不等式,再将各项合并成f[i][j+1]+f[i+1][j]从而完成证明。

        ③证明K[i][j-1]<=K[i][j]<=K[i+1][j],证明K[i][j-1]<=K[i][j]时,要先假设f[i][j-1]取得最优解时k=y,然后利用x<=y<=j-1<j列一个四边形不等式,然后在不等式两边添加一定的项试图得到f[i][j-1](k=x)+f[i][j](k=y)<=f[i][j-1](k=y)+f[i][j](k=x),也就是f[i][j-1](k=x)-f[i][j-1](k=y)<= f[i][j](k=x)-f[i][j](k=y),这时我们就会发现因为f[i][j-1](k=y)<=f[i][j-1](k=x),那么一定有f[i][j](k=y)<=f[i][j](k=x),也就是说对于所有小于y的x,都会有f[i][j-1](k=y)<=f[i][j-1](k=x),那么也都会有f[i][j](k=y)<=f[i][j](k=x),因此令f[i][j]取得最优解的k一定不小于y,这样就完成了对K[i][j-1]<=K[i][j]的证明。对于K[i][j]<=K[i+1][j]的证明是类似的。

    //O(P*V^2)
    #include<stdio.h>
    #include<string.h>
    #define MAXD 310
    #define MAXP 40
    int N, P, f[MAXP][MAXD], w[MAXD][MAXD], a[MAXD];
    void init()
    {
    int i, j, k;
    for(i = 1; i <= N; i ++)
    {
    scanf("%d", &a[i]);
    w[i][i] = 0;
    }
    for(k = 1; k < N; k ++)
    for(i = 1; (j = i + k) <= N; i ++)
    w[i][j] = w[i][j - 1] + a[j] - a[(i + j) / 2];
    }
    void solve()
    {
    int i, j, k;
    memset(f, 0x3f, sizeof(f));
    f[0][0] = 0;
    for(i = 1; i <= P; i ++)
    for(j = i; j <= N; j ++)
    for(k = i - 1; k < j; k ++)
    if(f[i - 1][k] + w[k + 1][j] < f[i][j])
    f[i][j] = f[i - 1][k] + w[k + 1][j];
    printf("%d\n", f[P][N]);
    }
    int main()
    {
    while(scanf("%d%d", &N, &P) == 2)
    {
    init();
    solve();
    }
    return 0;
    }
    //四边形不等式优化dp
    #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] + (t - x) * a[t] - (A[t - 1] - A[x - 1]);
    }
    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;
    }

     

  • 相关阅读:
    vue路由对象($route)参数简介
    原生js写ajax请求(复习)
    js,jq.事件代理(事件委托)复习。
    CSS 设置table下tbody滚动条
    H5 调用手机摄像机、相册功能
    css实现六边形图片(最简单易懂方法实现高逼格图片展示)
    input表单的type属性详解,不同type不同属性之间区别
    js对象,set和get方法 的三种实现形式
    day03 变量
    day01 js三种导入html的方法、js书写规范、变量的基本使用、变量提升
  • 原文地址:https://www.cnblogs.com/staginner/p/2391925.html
Copyright © 2020-2023  润新知