The main idea: give n points, ask you to go from the leftmost point to the rightmost point, each point must be traversed, and each point can only walk once, ask the shortest distance to form
The idea of solving a problem: using DP[I][J] to indicate that the first person walked to the point I, the second person walked to the first J Point and had traversed the shortest distance of all points of 1–max (I,J). Because dp[i][j] = Dp[j][i], so we set i > J
Then there is
When J < i-1, dp[i][j] = dp[i-1][j] + dis (i, i-1)
When j = = i + 1 o'clock the situation is more special, here will J with I-1 instead
Dp[i][i-1] = min (dp[i][i-1], dp[i-1][k] + dis (k,j))
Concrete proof can go to Baidu search: Double tune Euclid travel Quotient problem
There's another way of writing that I still don't understand.
#include <cstdio>#include <algorithm>#include <cstring>#include <cmath>using namespace STD;Const intN =1010;Const DoubleINF =0x3f3f3f3f3f3f3f3f;DoubleDp[n][n], dis[n][n];intNstructpoint{Doublex, y;} P[n];DoubleDistanceintAintb) {return sqrt((p[a].x-p[b].x) * (p[a].x-p[b].x) + (P[A].Y-P[B].Y) * (P[A].Y-P[B].Y));voidInit () { for(inti =1; I <= N; i++)scanf("%LF%LF", &p[i].x, &P[I].Y); for(inti =1; I <= N; i++) for(intj =1; J <= N; J + +) Dis[i][j] = dis[j][i] = distance (i,j);}DoubleSolve () {dp[2][1] = dis[2][1]; for(inti =3; I <= N; i++) {dp[i][i-1] = INF; for(intj =1; J < i-1; J + +) {dp[i][i-1] = min (dp[i][i-1], dp[i-1][J] + dis[j][i]); DP[I][J] = dp[i-1][J] + dis[i][i-1]; } }Doubleans = INF; for(inti =1; I < n; i++) ans = min (ans, dp[n][i] + dis[i][n]);returnAns;}intMain () { while(scanf("%d", &n)! = EOF && N) {init ();printf("%.2lf\n", solve ()); }return 0;}
UVA-1347 Tour double-tune Euclid travel Quotient problem