Title: poj1_1post office click to open the link
Question: N coordinates in a straight line are given to indicate the location of the village. Then, P post offices should be built on it. The villagers should first select the nearest post office, what is the minimum distance from all villages to the post office?
Category: interval DP
Analysis: For any village, there are only two options: Create a post office here or not, we can pre-process any two parts to establish the minimum distance of a post office W [I] [J]. For any two points, the optimal solution for setting up a post office is based on the median of the two points, that is, (I + J)/2, location.
For any two points I --- J, we can create an optimal result for the two post offices, which can be obtained by setting up one, enumerating the sub-points, separating them from the middle, building one before, and building one after. Then we can write the state and equation.
Definition status: DP [I] [J] indicates the minimum distance between the first I post offices.
Transition equation: DP [I] [J] = min (DP [I] [J], DP [k] [J-1] + W [k + 1] [I ]) (J-1 <= k <= i-1)
Note:
1: The DP direction of this question is the number of post offices, not the number of villages, there is a number of Post Offices 1 ---- P direction DP
2: note that after DP initialization, other values must be initialized within the loop. Otherwise, it is not necessarily optimal,
Code:
# Include <cstdio> # include <cstring> # include <algorithm> # include <iostream> # include <map> # include <cmath> using namespace STD; # define del (, b) memset (a, B, sizeof (A) const int n = 500; int W [N] [N]; int DP [N] [45]; int dis [N]; int main () {// freopen ("input.txt", "r", stdin); int N, K; while (~ Scanf ("% d", & N, & K) {for (INT I = 1; I <= N; I ++) scanf ("% d ", & dis [I]); del (W, 0); For (INT I = 1; I <= N; I ++) {for (Int J = I + 1; j <= N; j ++) {W [I] [J] = W [I] [J-1] + dis [J]-Dis [(I + J) /2];} // printf ("\ n");} del (DP, 0x3f3f3f); For (INT I = 1; I <= N; I ++) {DP [I] [1] = W [1] [I]; DP [I] [I] = 0 ;}for (Int J = 2; j <= K; j ++) {for (INT I = J + 1; I <= N; I ++) {DP [I] [J] = 0x3f3f3f3f; // note the standard writing for (int f = J-1; F <= I-1; F ++) DP [I] [J] = min (DP [I] [J], DP [f] [J-1] + W [F + 1] [I]);} printf ("% d \ n", DP [N] [k]);} return 0 ;}