zoukankan      html  css  js  c++  java
  • 村庄之间建立邮局

    There is a straight highway with villages alongside the highway. The highway is represented as an integer axis, and the position of each village is identified with a single integer coordinate. There are no two villages in the same position. The distance between two positions is the absolute value of the difference of their integer coordinates.

    Post offices will be built in some, but not necessarily all of the villages. A village and the post office in it have the same position. For building the post offices, their positions should be chosen so that the total sum of all distances between each village and its nearest post office is minimum.

    You are to write a program which, given the positions of the villages and the number of post offices, computes the least possible sum of all distances between each village and its nearest post office.
    Input
    Your program is to read from standard input. The first line contains two integers: the first is the number of villages V, 1 <= V <= 300, and the second is the number of post offices P, 1 <= P <= 30, P <= V. The second line contains V integers in increasing order. These V integers are the positions of the villages. For each position X it holds that 1 <= X <= 10000.
    Output
    The first line contains one integer S, which is the sum of all distances between each village and its nearest post office.
    Sample Input
    10 5
    1 2 3 6 7 9 11 22 44 50
    Sample Output
    9

    题意:在一条直线上面有 n 个村子,在一些村子上面建立邮局,求所有村子到最近的邮局的最小花费总和
    思路分析:
      一道经典的dp问题
      首先想一个问题,在任意一段区间上面如果我只建立一个村子,怎么建才会使花费最小呢?显然是应该建立在区间的中点的位置处,即(a+b)/2,的位置上,这里就存在一个小问题,就是当区间上的点若为奇数个时,此时最优的点是只有一个的,但当区间的点上有偶数个时,此时最优的点会是正中间的两个。
      基于这层关系,我们便可以 n^2的预处理出来任意两个村子间建立一个邮局的最小花费, dis[i][j] = dis[i][j-1]+d[j]-d[(i+j)/2]。
      然后考虑 dp, 先选取状态, dp[i][j]表示到第 i 个村子是时已经建立了 j 个邮局的最小花费,dp[i][j] = min(dp[i][j], dp[k][j-1]+dis[k+1][i])
    代码示例:(未测试,poj炸了。。)
    int n, m;
    int d[305];
    int dis[305][305], dp[305][305];
    
    int main() {
        //freopen("in.txt", "r", stdin);
        //freopen("out.txt", "w", stdout);
        
        cin >> n >> m;
        for(int i = 1; i <= n; i++){
            scanf("%d", &d[i]);        
        }
        for(int i = 1; i <= n; i++){
            for(int j = i+1; j <= n; j++){
                dis[i][j] = dis[i][j-1]+d[j]-d[(i+j)/2];
            }
        }   
        memset(dp, inf, sizeof(dp)); 
        for(int i = 1; i <= n; i++) {
            dp[i][1] = dis[1][i]; 
            dp[i][i] = 0;
        }
        for(int i = 3; i <= n; i++){
            for(int j = 2; j <= min(i, m); j++){
                for(int k = j-1; k < i; k++){
                    dp[i][j] = min(dp[i][j], dp[k][j-1]+dis[k+1][i]);
                    printf("%d %d %d
    ", i, j, dp[i][j]); 
                }
            }
        } 
        printf("%d
    ", dp[n][m]);
        return 0;
    }
    


    东北日出西边雨 道是无情却有情
  • 相关阅读:
    postgres 错误duplicate key value violates unique constraint 解决方案
    Golang包管理工具之govendor的使用
    《算法竞赛进阶指南》0x26广搜变形 HDOJ3085 双向BFS
    《算法竞赛进阶指南》0x26广搜变形 POJ3635
    《算法竞赛进阶指南》0x26广搜变形 电路维修 01最短路问题
    《算法竞赛进阶指南》0x25广度优先搜索 推箱子游戏 双重BFS
    《算法竞赛进阶指南》0x25广度优先搜索 多源floodfill
    《算法竞赛进阶指南》0x25广度优先搜索 POJ3322 Bloxorz I
    NETCORE
    VUE- 异步等待方法嵌套
  • 原文地址:https://www.cnblogs.com/ccut-ry/p/9131995.html
Copyright © 2011-2022 走看看