题意 :
有n个饭店,要求建k个供应点,要求每个供应点一定要建造在某个饭店的位置上,然后饭店都到最近的供应点拿货,求出所有饭店到最近的供应点的最短距离。
思路 : 一开始没看出来是DP,后来想想就想通了。预处理,如果要在下标为 i 到 j
的饭店建一个供应点,那一定是在下标为(i+j)/2的位置建造的,状态转移方程:dp[i][j] = dp[i-1][k-1]+dis[k][j](i <=
k <= j) ,dp[i][j]代表的是在前 j 个饭店中建了 i
个供应点的最小距离。方程代表的是在前k-1个饭店中已经建了i-1个供应点的最小距离再加上从第k个饭店到第j个饭店建一个供应点增加的距离。如果不明白可以看这里,链接
1 #include <iostream>
2 #include <stdio.h>
3 #include <string.h>
4 #include <math.h>
5
6 using namespace std;
7 const int maxn = 0x7fffffff ;
8
9 int a[210] ,dis[210][210],dp[210][210];
10
11 int main()
12 {
13 int n,k ,cas = 1;
14 while(~scanf("%d %d",&n,&k))
15 {
16 if(n == 0 && k == 0 ) break ;
17 for(int i = 1 ; i <= n ; i++)
18 scanf("%d",&a[i]) ;
19 for(int i = 1 ; i <= n ; i++)
20 {
21 for(int j = i ; j <= n ; j++)
22 {
23 dis[i][j] = 0 ;
24 for(int k = i ; k <= j ; k++)
25 dis[i][j] += fabs(a[k]-a[(i+j)/2] );26 }
27 }
28 memset(dp,0,sizeof(dp)) ;
29 for(int i = 1 ; i <= n ; i++)
30 dp[1][i] = dis[1][i] ;
31 for(int i = 2 ; i <= k; i++)
32 {
33 for(int j = 2 ; j <= n ; j++)
34 {
35 int minn = maxn ;
36 for(int k = i ; k <= j ; k++)
37 {
38 if(dp[i-1][k-1]+dis[k][j] < minn)
39 minn = dp[i-1][k-1]+dis[k][j] ;
40 }
41 dp[i][j] = minn ;
42 }
43 }
44 printf("Chain %d\nTotal distance sum = %d\n\n",cas++,dp[k][n]);
45 }
46 return 0;
47 }
HDU 1227 Fast Food (DP)