HDU 1227 Fast Food (DP)

题目链接

题意 : 有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
Total distance sum = %d

",cas++,dp[k][n]);
45     }
46     return 0;
47 }
View Code
原文地址:https://www.cnblogs.com/luyingfeng/p/3705914.html