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;
    }
    
  • 相关阅读:
    大同世界的Java 和.NET 开发
    关于Memcached 你了解多少?
    C#二进制与字符串之间的相互转换
    Nopcommerce主要用到的技术及特点
    小程序之路
    .NET方面的框架的整理和总结
    如何将FastReportOnlineDesign 灵活的应用到C/S B/S 程序当中?
    WebApi 的CRUD 的方法的应用
    关于EF 通用增删改查的封装
    基于Json序列化和反序列化通用的封装
  • 原文地址:https://www.cnblogs.com/hhlya/p/13138284.html
Copyright © 2011-2022 走看看