按横坐标增序给n个点,问从最左点走到最右点,再从最右点走到最左点的最小路程。
对此题进行转化:有两个人从最左点出发,终点是最右点。问两人怎样决策可以使得总路程最小。
不妨设 i > j
dp[i][j]表示一个人在i号点,另一个人在j号点,走到终点的最小路程。
对于下一个点,总有一个人要进行选择。
dp[i][j] = min (dp[i + 1][j] + dis(p[i] , p[i + 1]),dp[i + 1[i] + dis(p[j] , p[i + 1]));
struct Point { double x, y; Point(double _x = 0, double _y = 0) { x = _x; y = _y; } }; double dis(Point a, Point b) { return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y)); } double dp[1005][1005]; Point p[1005]; int main() { int n; double x, y; while (~scanf("%d", &n)) { for (int i = 1; i <= n; i++) scanf("%lf %lf", &p[i].x, &p[i].y); for (int i = 1; i < n; i++) { dp[n][i] = dis(p[n], p[i]); } for (int i = n - 1; i >= 2; i--) { for (int j = 1; j < i; j++) dp[i][j] = min(dp[i + 1][j] + dis(p[i], p[i + 1]), dp[i + 1][i] + dis(p[j], p[i + 1])); } printf("%.2f ", dp[2][1] + dis(p[1], p[2])); } }