Post Office pku1160 邮局

package pku1160;

/*在一条高速公路边上有V个村庄,用一条坐标轴来描述这条公路,每个村庄的坐标各不相同,
* 且都是整数。两个村庄间的距离用他们的坐标值差的绝对值表示。现在要在这些村庄中选
* 出P个建立邮局,邮局建立在村庄里,每个村庄使用离他最近的那个邮局。求一种建设方案,
* 使得所有村庄到各自所使用的邮局的距离总和最小。
*
* 算法: 动态规划 */

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import java.util.*;
public class Main {
 
/*Cost[j,i]表示安排前i个邮局给前j个村庄使用
   * D[i,j]表示在第i个到第j个村庄中建立一个邮局得到的最短距离总和。
   * D[a,b]可以利用关系式d[a,a]=0, D[a,b]=D[a,b-1]+x[b]-x[(a+b)/2]表示*/
public static void main(String[] args) {
   // TODO Auto-generated method stub
   Scanner cin = new Scanner(System.in);
   int n, m;
   n = cin.nextInt();
   m = cin.nextInt();
   int[] x = new int[n + 1];
   int[][] d = new int[n + 2][n + 2];
   int[][] cost = new int[n + 2][n + 2];
   for (int i = 1; i <= n; i++)
    x[i] = cin.nextInt();
   for (int i = 1; i <= n; i++){ 
    for (int j = 1; j <= n; j++){
     if (i >= j)
      d[i][j] = 0;
     else
      d[i][j] = d[i][j - 1] + x[j] - x[(i + j) / 2]; 
    }
   }
   for (int i = 1; i <= n; i++)
    cost[i][1] = d[1][i];
   for (int i = 2; i <= m; i++ ){ 
    for (int j = i + 1; j <= n; j++){
     int tmp = Integer.MAX_VALUE;
     for (int k = i - 1; k <= j; k++){
      if ( tmp > cost[k][i - 1] + d[k + 1][j] )
       tmp = cost[k][i - 1] + d[k + 1][j]; // Cost[n,m] = min{Cost[i,m-1]+D[i+1,n]},i=m-1,m,…,n-1。
     }
     cost[j][i] = tmp;
    }
   }
   System.out.println(cost[n][m]);
}
 
}

发表评论

电子邮件地址不会被公开。 必填项已用*标注


*

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>