• POJ 1160 Post Office


    题意:有n个村庄,要在其中m个村庄里建邮局,每个村庄去邮局的代价为当前村庄到最近的一个有邮局村庄的路程,问总最小代价是多少。

    解法:dp。dp[i][j]表示在前j个村庄建立i个邮局后的代价,则状态转移方程:dp[i][j] = min{dp[i - 1][k] + f(k + 1, j)},k = i - 1 ... j - 1,f(k + 1, j)表示在k + 1到j这些村庄中放一个邮局的代价,根据贪心的思想,这个邮局应该放在中间的村庄,即第(k + 1 + j) / 2个村庄,暴力的去算f会T,于是用数组sum[i][j]表示只有一个邮局在第i个村庄时,前j个村庄产生的代价,则邮局在第i个村庄时,从j到k村庄的代价为sum[i][k] - sum[i][j - 1]。

    代码:

    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    #include<string>
    #include<string.h>
    #include<math.h>
    #include<limits.h>
    #include<time.h>
    #include<stdlib.h>
    #include<map>
    #include<queue>
    #include<set>
    #include<stack>
    #include<vector>
    #define LL long long
    using namespace std;
    int v[305];
    int dp[35][305];
    int sum[305][305];
    int n, m;
    void init()
    {
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= n; j++)
                sum[i][j] = sum[i][j - 1] + abs(v[i] - v[j]);
    }
    int main()
    {
        while(~scanf("%d%d", &n, &m))
        {
            memset(dp, 0, sizeof dp);
            memset(sum, 0, sizeof sum);
            for(int i = 1; i <= n; i++)
            {
                scanf("%d", &v[i]);
            }
            sort(v, v + n);
            init();
            for(int i = 2; i <= n; i++)
            {
                int mid = (i + 1) >> 1;
                dp[1][i] = min(sum[mid][i], sum[mid + 1][i]);
            }
            for(int i = 2; i <= m; i++)
            {
                for(int j = i; j <= n; j++)
                {
                    dp[i][j] = 1000000;
                    for(int k = i - 1; k <= j - 1; k++)
                    {
                        int tmp = 0;
                        if(k + 1 == j) 
                        {
                            dp[i][j] = min(dp[i][j], dp[i - 1][k]);
                            continue;
                        }
                        int mid = (j + k + 1) >> 1;
                        tmp = min(sum[mid][j] - sum[mid][k], sum[mid + 1][j] - sum[mid + 1][k]);
                        dp[i][j] = min(dp[i][j], dp[i - 1][k] + tmp);
                    }
                }
            }
            printf("%d
    ", dp[m][n]);
        }
        return 0;
    }
    

      

  • 相关阅读:
    如何看待和选择基础设施软件
    target vs currentTarget, clientWidth vs offsetWidth
    undefined
    C# and android and socket
    hdu 4781 Assignment For Princess (2013ACMICPC 成都站 A)
    [置顶] Jquery中DOM操作(详细)
    hdu 4786 Fibonacci Tree (2013ACMICPC 成都站 F)
    android开发教程(八)——环境搭建之java-ndk
    cloudstack4.2+xenserver6.0.2 详细配置攻略
    11道php面试题
  • 原文地址:https://www.cnblogs.com/Apro/p/4857157.html
Copyright © 2020-2023  润新知