题意:
Spike is a bounty hunter and he is currently tracking a criminal! To investigate he uses his spaceship, the Swordfish II, and travels to Ndifferent places on 2D Euclidean space before returning to his crew at the starting location with all the information he has gathered. The starting location is the leftmost place (with the lowest x-coordinate) and Spike wants to travel to everyeveryother place before returning. However space fuel costs a lot of Woolongs and Spike would rather spend his money on special beef with bell peppers. Therefore he wants to travel the minimum possible distance.
On top of that he is being chased by the Red Dragon crime syndicate. To make sure they don’t catch him he can only visit places in increasing order of their xx-coordinate until he reaches the rightmost place (with the largest x-coordinate), then he can turn around and visit places in decreasing order of their x-coordinate until he reaches his starting location again.
Input
The input starts with an integer T(1≤T≤100) specifying the number of test cases that follow.
Each test case consists of an integer N(2≤N≤512) specifying the number of places in the tour.
The coordinates of these places are given as integers in the next NN lines, xx-coordinate first, yy-coordinate second (0≤x,y≤5000).
The places are given in ascending order of the x-coordinate.
Every place has a unique x-coordinate.
Output
For each test case, output on a single line the minimum travel distance needed to complete the tour.
Your output should have an absolute or relative error of at most 10^-2
样例输入
2
5
0 1
1 2
2 0
3 2
4 1
3
100 1
200 1
300 1
样例输出
9.300563079746
400
大概意思就是给T组样例,每组样例有n个地方,从最左边开始,从左往右走到最右边,再从最右边返回到最左边,每个点有且经过一次,求最短路径
思路:
我们找一个人从起点开始绕一圈的最短路,其实就是找两个人从起点到达终点(两个人除了终点和起点,不能经过相同的点)路径和的最小值。这是一个旅行商问题。由于505数值太大,因此可以用多路dp来求解
我们设dp【i】【j】保证第一个人到达i点,第二个人到达j点,i < j且j之前的所有点都经过的最小花费,有关递推式在代码中有标注
代码:
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>
#define inf 0x3f3f3f3f
using namespace std;
struct node {
double x, y;
}point[550];
bool zfq (node A, node B) {
return A.x < B.x;
}
double sq(node A, node B) {
return sqrt((A.x - B.x) * (A.x - B.x) + (A.y - B.y) * (A.y - B.y));
}
double dp[550][550]; //dp[i][j]保证第一个到达i点,第二个人到达j点,i < j且j之前的所有点都经过的最小花费
double d[550][550];
int main() {
int T, n;
scanf("%d", &T);
while (T--) {
double ans = inf;
scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%lf%lf", &point[i].x, &point[i].y);
}
sort(point, point + n, zfq);
for (int i = 0; i < n; i ++) {
for (int j = i + 1; j < n; j++) {
dp[i][j] = inf;
d[i][j] = sq(point[i], point[j]);
}
}
dp[0][1] = d[0][1];
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
dp[j][j + 1] = min (dp[j][j + 1], dp[i][j] + d[i][j + 1]);//可能是i走到j+1
dp[i][j + 1] = min (dp[i][j + 1], dp[i][j] + d[j][j + 1]);//也可能是j走到j+1
}
}
for (int i = 0; i < n - 1; i ++) {
ans = min(ans, dp[i][n - 1] + d[i][n - 1]); //由于i<j,所以需额外加一个for循环求dp[n-1][n-1]的最小值
}
printf("%f\n", ans);
}
return 0;
}
如果有写的不对或者不全面的地方 可通过主页的联系方式进行指正,谢谢