UVA 662 Fast Food(DP)

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 restaurent 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  (these
are the distances measured from the company‘s headquarter, which happens to be at the same highway). Furthermore, a number  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 .
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

考虑dp状态为dp[i][j]:前i个酒店建k个仓库的最小代价。
dp[i][j]=min(dp[k][j-1]+dis[k+1][i])(j-1<=k<i);
关于路径输出设path[i][j]为达到dp[i][j]状态的前一状态的末仓库。
易知道path[i][1]=0;
其他的就是递归输出了。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<string>
#include<iostream>
#include<queue>
#include<cmath>
#include<map>
#include<stack>
#include<bitset>
using namespace std;
#define REPF( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define CLEAR( a , x ) memset ( a , x , sizeof a )
typedef long long LL;
typedef pair<int,int>pil;
const int INF = 0x3f3f3f3f;
const int maxn=220;
int dis[maxn][maxn];
int dp[maxn][50];
int path[220][50];
int d[220];
int n,k,cnt;
int cal(int l,int r)
{
    int sum=0;
    int mid=(l+r)>>1;
    for(int i=l;i<=r;i++)
        sum+=abs(d[mid]-d[i]);
    return sum;
}
void print(int i,int x)
{
    if(x==0)
        return ;
    print(path[i][x],x-1);
    printf("Depot %d at restaurant %d serves restaurants %d to %d\n",x,(path[i][x]+1+i)/2,path[i][x]+1,i);
}
int main()
{
    int cas=1;
    while(~scanf("%d%d",&n,&k)&&(n+k))
    {
        CLEAR(dp,INF);
        CLEAR(path,0);cnt=1;
        REPF(i,1,n)  scanf("%d",&d[i]);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
               dis[i][j]=cal(i,j);
        for(int i=1;i<=n;i++)
        {
            dp[i][1]=dis[1][i];
            path[i][1]=0;
        }
        for(int i=1;i<=n;i++)
        {
            for(int j=2;j<=k;j++)
            {
                for(int p=j-1;p<i;p++)
                    if(dp[p][j-1]+dis[p+1][i]<dp[i][j])
                    {
                        dp[i][j]=dp[p][j-1]+dis[p+1][i];
                        path[i][j]=p;//上个区间
                    }
            }
        }
        printf("Chain %d\n",cas++);
        print(n,k);
        printf("Total distance sum = %d\n\n",dp[n][k]);
    }
    return 0;
}

/*

*/

时间: 2024-10-29 18:51:22

UVA 662 Fast Food(DP)的相关文章

DP(递归打印路径) UVA 662 Fast Food

题目传送门 题意:n个饭店在一条直线上,给了它们的坐标,现在要建造m个停车场,饭店没有停车场的要到最近的停车场,问所有饭店到停车场的最短距离 分析:易得区间(i, j)的最短距离和一定是建在(i + j) / 2的饭店,预处理出(i, j)的距离和sum[i][j],mark[i][j] 表示区间的最优停车场的位置,mid[i][j]表示(i + j) / 2.状态转移方程:dp[i][j] = max (dp[k-1][j-1] + sum[k][i]): 收获:学习递归打印路径 代码: /*

UVa 662 - Fast Food

题目:一条街道上有n家餐馆,现在想建立k个仓库,储存代价是每个餐馆到最近的仓库的距离和: 求最小的储存代价. 分析:dp,中位数,动态规划. 状态:f(i,j)表示前j家餐馆建立i个仓库的最小储存代价: 状态转移:f(i,j)= min(f(i-1,k)+ cost(k+1,j)){ 其中 i-1 < k < j }: 其中cost(k+1,j)是在k+1,..,到j间建立一个仓库供这j-k个餐馆使用的最小单价: 此时,必然建立在中位数位置:存储路径递归逆序输出即可. 说明:之前写的不是永中位

UVA 662 Fast Food +经典动态规划

题目链接:点击进入 以前也碰到过这种类型的dp,感觉就是状态不好定义和转移:原来定义状态的时候总是认为dp[i][j]就应该由dp[i-1][j-1]转移而来,这样的话就会导致需要记忆前面i-1步的所有状态,然后就是转移方程没法写了.对于这道题,我们定义状态dp[i][j]表示前j个餐馆建立i个仓库时的最小代价,然后状态转移为dp[i][j]=dp[i-1][k-1]+cost[k][j],意思是:已经建立的前i-1个仓库负责前k-1个餐馆,然后第i个餐馆负责第k–j个餐馆,其中k<=i<=j

Problem W UVA 662 二十三 Fast Food

Fast Food Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Status Practice UVA 662 Appoint description:  System Crawler  (2015-08-27) Description The fastfood chain McBurger owns several restaurants along a highway. Recen

uva 662

dp +路径输出 #include <cstdio> #include <cstdlib> #include <cmath> #include <stack> #include <vector> #include <sstream> #include <cstring> #include <string> #include <map> #include <set> #include &l

[UVA 12589]Learning Vector[DP]

题目链接:[UVA 12589]Learning Vector[DP] 题意分析:给出n个矢量,从中选择k个,以坐标原点为起点,收尾相连,问:这样的k个周围相连矢量与x轴围成图形的最大面积的两倍是多少? 解题思路:考虑状态:dp[id][pick][h]代表到第id个矢量为止,选择pick个矢量离最大面积还差多少,h为当前图形最右端高度.具体转移看代码. 这里着重说一下为什么要对这些矢量按斜率进行排序: 首先,整个求解过程其实就是在暴力枚举这些向量的组合,只不过采用了记忆化搜索优化. 其次,对于

Uva 12018 Juice Extractor dp

题目链接:点击打开链接 题意: 切水果游戏 给出n个水果 水果出现在屏幕上的时间的区间 1.每次切会把屏幕上所有水果切完 2.当同时切3个或以上时计分,分数为切的水果个数 3.不能遗漏水果 问最高得分 dp[i] 表示 最后一次切第i个的得分. #include<stdio.h> #include<algorithm> #include<string.h> #include<iostream> using namespace std; #define N 1

uva 11578 - Situp Benches(dp+输出路径)

题目连接:uva 11578 - Situp Benches 题目大意:健身房有两个仪器,初始角度为10度,每次有人使用需要交15元,每调10度需要花费10元,现在有n个人,给出每个人使用仪器的顺序和角度,保证不会同时有大于2个人序号一样,求最小花费,并且输出每个人分别使用哪一个仪器,并且所有人使用结束后,要将仪器调回10度. 解题思路:dp[i][x][y]表示第i个人,一个仪器为x,另一个仪器为y的情况,path[i][x][y]记录的是它的前一个状态,[0]为前一个仪器的夹角,[1]为另一

uva 10269 最短路+dp

题意:有a个村庄.b个城镇, 编号分别为:1-a , a+1--a+b . 有双神奇的鞋,可以瞬时移动,可以使用k次,每次可以移动L , 但穿这双鞋的时候,不能经过城镇 , 问:从a+b 到 1 最短距离是多少? 刚开始看这个题时 , 一点思路都没有 , dp类型的题目做得太少了. 解法:进行状态压缩, 用点+使用鞋子的次数 , 来表示一个状态 , d[i][k] , 表示到 点 i 使用 k 次鞋子的最短距离是多少. 但要先进行初始化 , 求任意点之间不经过城镇的最短距离 , 用floyd算法