题目给出一条直线上的m个村庄及其距离,给出n个邮局,要求怎么建n个邮局使代价最小。
思路:用opt[i][j]记录把前i个邮局建到前j个村庄中的最优解,用cost[i][j]记录所有在i到j村庄中,建1个邮局的最小代价。显然邮局应该设到中点。让前i个邮局覆盖前j个村庄,第i+1个邮局覆盖第j+1至j+k个村庄(j+k<=n),则状态转移方程为
res[i+1][j+k]=min{res[i][j]+cost[j+1][j+k];} (k+j<=n)
Cost数组存放从i到j中有一个邮局的最小代价,显然该邮局应该放在中间,构造cost的代码参考后边贴的代码。
样例数据:
Cost[i][j] |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
1 |
0 |
1 |
2 |
6 |
10 |
16 |
21 |
37 |
74 |
117 |
2 |
|
0 |
1 |
4 |
8 |
11 |
16 |
31 |
68 |
109 |
3 |
|
|
0 |
3 |
4 |
7 |
11 |
26 |
61 |
102 |
4 |
|
|
|
0 |
1 |
3 |
7 |
20 |
55 |
94 |
5 |
|
|
|
|
0 |
2 |
4 |
17 |
50 |
89 |
6 |
|
|
|
|
|
0 |
2 |
13 |
46 |
74 |
7 |
|
|
|
|
|
|
0 |
11 |
33 |
61 |
8 |
|
|
|
|
|
|
|
0 |
22 |
28 |
9 |
|
|
|
|
|
|
|
|
0 |
6 |
10 |
|
|
|
|
|
|
|
|
|
0 |
res[i][j] 表示前i个邮局覆盖前j个村庄的最小代价,对于i=1来说,res[i][j] = cost[i][j],让前2个邮局覆盖前j个村庄,也就是i=2的情况,可能是一下情况的最优解:第一个邮局覆盖第一个村庄,第二个村庄覆盖2-j个村庄,或者第一个邮局覆盖第1-2个村庄,第二个村庄覆盖3-j个村庄,第一个邮局覆盖第1-3个村庄,第二个村庄覆盖4-j个村庄,等等等等。该部分的代码如下: