zoukankan      html  css  js  c++  java
  • HDU 1227 Fast Food (DP)

    题面

    Problem Description
    The fastfood chain McBurger owns several restaurants along a highway. Recently, they have decided to build several depots along the highway, each one located at a restaurant and supplying several of the restaurants with the needed ingredients. Naturally, these depots should be placed so that the average distance between a restaurant and its assigned depot is minimized. You are to write a program that computes the optimal positions and assignments of the depots.

    To make this more precise, the management of McBurger has issued the following specification: You will be given the positions of n restaurants along the highway as n integers d1 < d2 < ... < dn (these are the distances measured from the company's headquarter, which happens to be at the same highway). Furthermore, a number k (k <= n) will be given, the number of depots to be built.

    The k depots will be built at the locations of k different restaurants. Each restaurant will be assigned to the closest depot, from which it will then receive its supplies. To minimize shipping costs, the total distance sum, defined as

    must be as small as possible.

    Write a program that computes the positions of the k depots, such that the total distance sum is minimized.

    Input
    The input file contains several descriptions of fastfood chains. Each description starts with a line containing the two integers n and k. n and k will satisfy 1 <= n <= 200, 1 <= k <= 30, k <= n. Following this will n lines containing one integer each, giving the positions di of the restaurants, ordered increasingly.

    The input file will end with a case starting with n = k = 0. This case should not be processed.

    Output
    For each chain, first output the number of the chain. Then output a line containing the total distance sum.

    Output a blank line after each test case.

    Sample Input
    6 3
    5
    6
    12
    19
    20
    27
    0 0

    Sample Output
    Chain 1
    Total distance sum = 8

    分析

    一道dp见祖宗,hha。我们来看看,这道题的dp设定,首先呢,dp关系肯定是取min,然后分析dp[i][j]这个状态,我们考虑怎么取状态,如果考虑第i到第j这个区间放多少个仓库,那么显然这是不对了,因为你稍微想一下,这并不符合状态转移,反而有点想小暴力了。所以我们充分利用仓库个数这个点,将上面的dp[i][j]的状态表示为前j个店铺放i个仓库,则它的状态可以变为dp[i-1][k]+cost(k+1,j),可以发现我们掉了一个仓库,并且减掉了一个区间,所以就是说我们去掉的这个区间一定只放了一个仓库,而这个区间的大小为i-1到j-1,想一想,为什么?那么问题就变成了,我们有一个区间,我们只在这个区间放一个仓库如何使距离最小,这个问题很好想把!怎么说呢,dp的题目怎么说也是个玄学,还是要多做题目,这道题目么,关键就在于仓库数和区间数,我们可以想到的是在一个区间放一个仓库的最优决策,所以我们要尽量用这个来完成dp转移。

    代码实现

    c++
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<iostream>
    #include<vector>
    using namespace std;
    #define eps 1e-4
    const int maxn=50005;
    int dp[32][250];
    int dis[maxn];
    int n,m,ca=1;
    int cost (int x,int y) {
       int ans=0;
       int mid = dis[(x+y)/2];
       for (int k=x;k<=y;k++) {
          ans+=abs(dis[k]-mid);
       }
       return ans;
    }
    int main () {
       while (cin>>n>>m) {
          if (n==0&&m==0) break;
          for (int i=1;i<=n;i++) cin>>dis[i];
          memset (dp,0x3f3f3f3f,sizeof (dp));
          for (int i=1;i<=n;i++) {
             dp[1][i]=cost(1,i);
          }
          for (int i=2;i<=m;i++) 
           for (int j=1;j<=n;j++) {
             for (int k=i-1;k<=j-1;k++) {
                dp[i][j]=min (dp[i][j],dp[i-1][k]+cost(k+1,j));
             }
           }
           printf ("Chain %d
    ",ca++);
           printf ("Total distance sum = ");
           cout<<dp[m][n]<<endl;
       }
        return 0;
    }
    
  • 相关阅读:
    直线的中点Bresenham算法的实现
    使用git 将自己的本地文件git到github上面的完整过程
    利用Microsoft VC++6.0 的MFC 的绘图工具实现简单图形的绘制
    github常见操作和常见错误及其解决办法
    浅谈软件配置管理工具(github & SVN)
    为Github 托管项目的访问添加SSH keys
    jQuery:用 lightTreeview 实现树形分类菜单的功能 展开收缩分类代码
    程序设计7大面向对象设计原则
    计算机组成原理实验之模拟整机实验考核试题
    计算机组成原理实验之CPU组成与指令周期实验
  • 原文地址:https://www.cnblogs.com/hhlya/p/13138284.html
Copyright © 2011-2022 走看看