1206 POJ1485 Fast Food

来源:互联网 发布:cnn图片相似度算法 编辑:程序博客网 时间:2024/06/05 04:03
摘要
同一条路上的餐馆,要修建仓库depots;给定仓库的数量和这条路上所有餐馆的位置;求合理的分配方式(总的餐馆距最近的depot距离之和最小);
原题目摘要
-Fast Food 
http://poj.org/problem?id=1485

-

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

n
∑ |di - (position of depot serving restaurant i)|
i=1

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 an optimal placement of the depots as follows: for each depot output a line containing its position and the range of restaurants it serves. If there is more than one optimal solution, output any of them. After the depot descriptions output a line containing the total distance sum, as defined in the problem text.

Output a blank line after each test case.

Sample Input

6 3
5
6
12
19
20    
27
0 0

Sample Output

    

Chain 1
Depot 1 at restaurant 2 serves restaurants 1 to 3
Depot 2 at restaurant 4 serves restaurants 4 to 5
Depot 3 at restaurant 6 serves restaurant 6
Total distance sum = 8


题目理解
-这个题目想了好久。最后通过搜索结合记忆化把它解决了;对于给定的k个depots 与 n个餐馆;总可以找到至少一个点满足要求 这个点搜索的话 是 min(dp(1,begin,mid)+(k-1,mid+1,end)) mid的取值范围是begin到end-k+1;如果用三维数组 中间很多没用上;利用两个二维数组;Dij[][];用来储存任意的i到j之间有一个depot时的距离和;Dki[][]用来记录分割数据,从i到结束中间用k个depots时的距离总和,每个分割点记录分割起点b,分割偏移pos,当前i到end分配距离总和,下一个分割点*next;
注意
-输出的是时候摔了跟头;单个和多个的restaurant(s);最后一个分割的输出;与前面的不同;每个测试数据间有一空行。
日期
-2017 12 6
附加
-
代码

#include <algorithm>#include <cstdio>#include <iostream>#include <cstring>#include <memory>#define MAX 205using namespace std;struct Node{    int b;   int pos;//next div pos   int cur_total;//B TO END AL LCOST   Node *next;   void init(int _b){       b=_b;next=NULL;cur_total = pos= -1;   }};int D[MAX];int n,k;int id;int Dij[MAX][MAX];//use getij();Node Dki[31][MAX];//use for the dp();int getDij(int b,int e){    if(Dij[b][e]!=-1) return Dij[b][e];    int cur=0;    int p = (b+e)/2;    for(int i=b;i<=e;i++){        cur+=abs(D[p]-D[i]);    }    return Dij[b][e]=cur;}Node dp(int _k,int _b){//cout<<_k<<" "<<_b<<" "<<Dki[_k][_b].cur_total<<endl;    if(Dki[_k][_b].pos!=-1) return Dki[_k][_b];    Node &node  = Dki[_k][_b];    node.b = _b;    if(_k==1){        node.pos = (n-1+_b)/2-_b;        node.cur_total = getDij(_b,n-1);        node.next = NULL;        return Dki[_k][_b];    }    node.cur_total = dp(_k-1,_b+1).cur_total;    node.next = &Dki[_k-1][_b+1];    node.pos = 0;    int temp;    for(int i=1;_b+i<=n-_k;i++){        temp = getDij(_b,_b+i)+dp(_k-1,_b+i+1).cur_total;        if(temp<node.cur_total){            node.cur_total = temp;            node.next = &Dki[_k-1][_b+i+1];            node.pos = i;        }    }    return Dki[_k][_b];}void show_node(Node *it,int o){        int b=it->b+1;        int e=b+it->pos;        int p=b+it->pos/2;    if(o==k){//last depot        p=e;        e=n;    }     printf("Depot %d at restaurant %d serves restaurant",               o,p);    if(b!=e)printf("s %d to %d\n",b,e);    else printf(" %d\n",b);}void solve(){    for(int i=0;i<n;i++)scanf("%d",&D[i]);    for(int i=1;i<=k;i++){        for(int j=0;j<n;j++)                Dki[i][j].init(j);    }    memset(Dij,-1,sizeof(Dij));    dp(k,0);    Node *ans = &Dki[k][0];    printf("Chain %d\n",id);    int o=1;    int total=ans->cur_total;    while(ans){        show_node(ans,o);o++;        ans = ans->next;    }    printf("Total distance sum = %d\n\n",total);}int main(){    freopen("in","r",stdin);    id = 0;    while( scanf("%d%d",&n,&k)&&n){        id++;solve();    }    return 0;}


原创粉丝点击