|
思路:
一个 O(N^3) 的动态规划,由于 N 比较小,所以没啥问题。 f[i][j][k] = { 从一开始到三辆车分别位于 i, j, k 的时候,所有车走过的距离之和的最小值 } 其中 i <= j <= k 状态转移: 1. 第一辆车走到 k + 1 2. 第二辆车走到 k + 1 3. 第三辆车走到 k + 1
注意: 两点之间的距离跟输入一致。 不可以计算两点间的最短距离,这样会 WA。 这是题目没有描述清楚!
#include <stdio.h>
#define MAX_N 32 #define MAX_DIS 0x70000000
int M, N; int D[MAX_N][MAX_N]; int dp[MAX_N][MAX_N][MAX_N];
inline void update(int *a, int b) { if (b < *a) *a = b; }
int main() { int i, j, k, v;
freopen("e:\\test\\in.txt", "r", stdin);
scanf("%d", &M); while (M--) { scanf("%d", &N); for (i = 1; i <= N - 1; i++) { for (j = i + 1; j <= N; j++) { scanf("%d", &v); D[i][j] = D[j][i] = v; } } /**//* 两点之间的距离跟输入一致。 不可以计算两点间的最短距离,这样会 WA。 这是题目没有描述清楚! for (k = 1; k <= N; k++) for (i = 1; i <= N; i++) for (j = 1; j <= N; j++) if (D[i][k] + D[k][j] < D[i][j]) D[i][j] = D[i][k] + D[k][j]; */ for (i = 1; i <= N; i++) for (j = 1; j <= N; j++) for (k = 1; k <= N; k++) dp[i][j][k] = MAX_DIS; dp[1][1][1] = 0; for (i = 1; i <= N - 1; i++) { for (j = 1; j <= i; j++) { for (k = j; k <= i; k++) { update(&dp[k][i][i + 1], dp[j][k][i] + D[j][i + 1]); update(&dp[j][i][i + 1], dp[j][k][i] + D[k][i + 1]); update(&dp[j][k][i + 1], dp[j][k][i] + D[i][i + 1]); } } } v = MAX_DIS; for (i = 1; i <= N; i++) for (j = i; j <= N; j++) update(&v, dp[i][j][N]); printf("%d\n", v); }
return 0; }
|