Meaning
There are n hotels on a straight road, and each coordinate is di.
Choose K Hotel in n restaurants to build a parking lot. A hotel without a parking lot can only use the nearest parking lot nearby.
Ask for the minimum total distance of the construction scheme and output.
Ideas
First pretreatment, Sum[i][j] said that a car park between the hotel I~j, i~j all hotels to the parking lot distance and the smallest.
Between the hotel I~j, the option to build at (I+J)/2 is the minimum total distance scheme
F[I][J], representing the minimum total distance of the J-car park for the former I Hotel
So
F[I][J] = min{F[k-1][j] + sum[k][i], 1<=k<=i}
As for the output scheme, the DP output scheme is generally to save the "decision" record, and then the recursive output can be.
Code
/**========================================== * is a solution for ACM/ICPC problem * * @source: uva-662 Fast Foo D * @type: DP * @author: Shuangde * @blog: blog.csdn.net/shuangde800 * @email: zengshuangde@gmail.com *=================== ========================*/#include <iostream> #include <cstdio> #include <algorithm> #include <
vector> #include <queue> #include <cmath> #include <cstring> using namespace std;
typedef long long Int64;
const int INF = 0X3F3F3F3F;
const int MAXN = 210;
int n, K;
int D[MAXN], f[maxn][35], SUM[MAXN][MAXN];
int MARK[MAXN][MAXN], MID[MAXN][MAXN];
int idx;
void print (int i, int j) {if (I < 1 | | J < 1) return;
Print (Mark[i][j]-1, j-1);
printf ("Depot%d at restaurant%d serves restaurant", idx++, Mid[mark[i][j]][i]);
if (mark[i][j] = = i) {printf ("%d\n", I);} else {printf ("s%d to%d\n", mark[i][j], i); the int main () {int cas = 1; while (~SCANF ("%d%D ", &n, &k) && n + k) {for (int i = 1; I <= n; ++i) scanf ("%d ", &d[i));
memset (sum, 0, sizeof (sum)); for (int i = 1; I <= n; ++i) {mid[i][i] = i; for (int j = i + 1; j <= N; ++j) {int m = (j + i) >> 1; mid[i][
j] = m;
for (int k = i; k <= J; ++k) {Sum[i][j] + + ABS (D[k]-d[m]);}
for (int i = 1; I <= n; ++i) for (int j = 0; j <= K; ++j) f[i][j] = INF;
memset (F[0], 0, sizeof (f[0)); for (int i = 1; I <= n; ++i) for (int j = 1; j <= K; ++j) {for (int k = 1; k <= i; ++k) {int tmp = F[K-1][J-
1] + sum[k][i];
if (tmp <= f[i][j]) {mark[i][j] = k; F[i][j] = tmp;}}
printf ("Chain%d\n", cas++);
IDX = 1;
Print (n, k);
printf ("Total distance sum =%d\n\n", f[n][k]);
return 0; }