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\n",ca++);
       printf ("Total distance sum = ");
       cout<<dp[m][n]<<endl;
   }
    return 0;
}
posted @ 2020-06-15 22:29  Luglucky  阅读(130)  评论(0编辑  收藏  举报