题目给出一条直线上的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个村庄,等等等等。该部分的代码如下: