1. 程式人生 > >162:Post Office

162:Post Office

sam input con class some end itl res out

162:Post Office

總時間限制:
1000ms
內存限制:
65536kB
描述
There is a straight highway with villages alongside the highway. The highway is represented as an integer axis, and the position of each village is identified with a single integer coordinate. There are no two villages in the same position. The distance between two positions is the absolute value of the difference of their integer coordinates.

Post offices will be built in some, but not necessarily all of the villages. A village and the post office in it have the same position. For building the post offices, their positions should be chosen so that the total sum of all distances between each village and its nearest post office is minimum.

You are to write a program which, given the positions of the villages and the number of post offices, computes the least possible sum of all distances between each village and its nearest post office.
輸入
Your program is to read from standard input. The first line contains two integers: the first is the number of villages V, 1 <= V <= 300, and the second is the number of post offices P, 1 <= P <= 30, P <= V. The second line contains V integers in increasing order. These V integers are the positions of the villages. For each position X it holds that 1 <= X <= 10000.
輸出
The first line contains one integer S, which is the sum of all distances between each village and its nearest post office.
樣例輸入
10 5
1 2 3 6 7 9 11 22 44 50
樣例輸出
9
來源
IOI 2000
/*
1、考慮在V個村莊中只建立一個郵局的情況,顯然可以知道,將郵局建立在中間的那個村莊即可。也就是在a到b間建立

一個郵局,若使消耗最小,則應該將郵局建立在(a+b)/2這個村莊上。

2、下面考慮建立多個郵局的問題,可以這樣將該問題拆分為若幹子問題,在前i個村莊中建立j個郵局的最短距離,是

在前k個村莊中建立j-1個郵局的最短距離與 在k+1到第i個郵局建立一個郵局的最短距離的和。而建立一個郵局我們在

上面已經求出。

3、狀態表示,由上面的討論,可以開兩個數組

dp[i][j]:在前i個村莊中建立j個郵局的最小耗費

sum[i][j]:在第i個村莊到第j個村莊中建立1個郵局的最小耗費

那麽就有轉移方程:dp[i][j] = min(dp[i][j],dp[k][j-1]+sum[k+1][i]) DP的邊界狀態即為dp[i][1] = sum[1][i];

所要求的結果即為dp[V][P];

4、然後就說說求sum數組的優化問題,可以假定有6個村莊,村莊的坐標已知分別為p1,p2,p3,p4,p5,p6;那麽,如果要

求sum[1][4]的話郵局需要建立在2或者3處,放在2處的消耗為p4-p2+p3-p2+p2-p1=p4-p2+p3-p1放在3處的結果為p4-

p3+p3-p2+p3-p1=p4+p3-p2-p1,可見,將郵局建在2處或3處是一樣的。現在接著求sum[1][5],現在處於中點的村莊是

3,那麽1-4到3的距離和剛才已經求出了,即為sum[1][4],所以只需再加上5到3的距離即可。同樣,求sum[1][6]的時候

也可以用sum[1][5]加上6到中點的距離。所以有遞推關系:sum[i][j] = sum[i][j-1] + p[j] -p[(i+j)/2]
*/

#include<iostream>
using namespace std;
int dp[310][40] = {}, sum[310][310] = {}, loc[310] = {};
int main() {
int V, P;
cin >> V >> P;
for (int i = 1; i <= V; i++) cin >> loc[i];
for (int i = 1; i < V; i++)
for (int j = i + 1; j <= V; j++)
sum[i][j] = sum[i][j - 1] + loc[j] - loc[(i + j) / 2];
for (int i = 1; i <= V; i++) dp[i][1] = sum[1][i];
for (int k = 2; k <= P; k++)
for (int j = k + 1; j <= V; j++) {
dp[j][k] = 0x7FFFFFFF;
for (int i = k - 1; i < j; i++)
dp[j][k] = min(dp[j][k], dp[i][k - 1] + sum[i + 1][j]);
}
cout << dp[V][P] << endl;
}

162:Post Office