练习场hit1005:fast food

题目:

  (这算是我真正理解了动态规划的第一道题吧,原题记录如下)

  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

练习场hit1005:fast food

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
思路:
  
  这是我第一次顺利运用动态规划。我现在感觉,公式也罢表格也罢,动态规划其实代表着最直接最凶残的一种思想。动态规划往往要解决的,是由两个条件变量制约的一个变量在给出两个条件变量精确取值时的值。那么动态规划的思想就是直捣黄龙,直接指向这个值。既然和两个变量有关,那就以两个条件变量为横纵坐标排出一张表。既然复杂情况可由简单情况一步步叠加而来,那就再找到得到复杂情况的公式,于是问题解决。过程清晰,目标明确,空间换时间,十分霸道。
 
方案:
  
  首先,如果是n个快餐店由1个供给站负责,那么这个供给站无疑建立在第n/2个快餐店位置(单数取中值任意最近无所谓)。总距离也随之可得。建立表dis_tab[n][n].dis_tab[i][j]:从第i+1到第j+1个快餐店只由1个供给站负责时需要的总距离。该表所有值可直接得出。
  
  其次,建立表tol_dis[k][n].tol_dis[i][j]:从1到第j+1个快餐店,配i+1个供给站时能够得到的最小总距离。则有,tol_dis[i][j]=min(tol_dis[i-1][j-1]+dis_tab[j][j],tol_dis[i-1][j-2]+dis_tab[j-1][j],...,tol_dis[i-1][i]+dis_tab[i+1][j]).可由此算出。
  
  最后,返回值tol_dis[k-1][n-1].
 
代码:
 
练习场hit1005:fast food
 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <string.h>
 4 
 5 #define MAX_N 200
 6 
 7 int TolDisCaculate(int n,int k,int *nlist);
 8 
 9 int main()
10 {
11     int n,k,i;
12     scanf("%d %d",&n,&k);
13     int nlist[MAX_N];
14     int cnt=1;
15     while(n!=0&&k!=0)
16     {
17         memset(nlist,0,sizeof(int)*MAX_N);
18         for(i=0;i<=n-1;++i)
19             scanf("%d",&nlist[i]);
20         printf("Chain %d\nTotal distance sum = %d\n\n",cnt++,TolDisCaculate(n,k,nlist));
21         scanf("%d %d",&n,&k);
22     }
23     return 0;
24 }
25 
26 int TolDisCaculate(int n,int k,int *nlist)
27 {
28     int **dis_tab=(int **)malloc(sizeof(int *)*n);
29     int i,j,z,mid;
30     for(i=0;i<=n-1;++i)
31     {
32         dis_tab[i]=(int *)malloc(sizeof(int)*n);
33         memset(dis_tab[i],0,sizeof(int)*n);
34         for(j=i;j<=n-1;++j)//dis_tab建立过程
35         {
36             mid=(i+j)>>1;
37             for(z=i;z<=j;++z)
38                 if(z<mid)
39                     dis_tab[i][j]+=nlist[mid]-nlist[z];
40                 else
41                     dis_tab[i][j]+=nlist[z]-nlist[mid];
42         }
43     }
44     int **tol_dis=(int **)malloc(sizeof(int *)*k);
45     for(i=0;i<=k-1;++i)
46     {
47         tol_dis[i]=(int *)malloc(sizeof(int )*n);
48         memset(tol_dis[i],0,sizeof(int)*n);
49     }
50     for(i=1;i<=n-1;++i)
51         tol_dis[0][i]=dis_tab[0][i];
52     int tmp_min;
53     
54     for(i=1;i<=k-1;++i)//tol_dis增长过程
55         for(j=i;j<=n-1;++j)
56         {
57             tmp_min=tol_dis[i-1][i-1]+dis_tab[i][j];
58             for(z=i;z<=j-1;++z)
59                 if(tol_dis[i-1][z]+dis_tab[z+1][j]<tmp_min)
60                     tmp_min=tol_dis[i-1][z]+dis_tab[z+1][j];
61             tol_dis[i][j]=tmp_min;
62             
63         }
64     return tol_dis[k-1][n-1];
65 }
练习场hit1005:fast food

 

心得:

  原来公式和表都不是动态规划的真正思想。

练习场hit1005:fast food

上一篇:CCDictionary


下一篇:【原创】本科生活