Question link: http://acm.timus.ru/problem.aspx? Space = 1 & num = 1143
Returns the coordinates of n (n <= 200) vertices of a convex hull counterclockwise to the length of a shortest Hamilton path.
Solution: finding the shortest Hamilton is an NP problem, but it can be used on a convex hull. There is a property that the shortest Hamilton path on the convex hull will not cross. Therefore, we can see that starting from a point, it is either connected to a clockwise adjacent point, or to a counter-clockwise adjacent point. Through this nature, we can do this through DP:
Ans [I] [J] [0] indicates the start of I, and the shortest path length of vertices in J later. ans [I] [J] [0] indicates the start of I, the shortest path length of vertices on the forward J;
For the transfer equation, see the code: With the transfer equation enumerative, the first starting position is the line, and the complexity is n ^ 3.
/******************************************************* @author:xiefubao*******************************************************/#pragma comment(linker, "/STACK:102400000,102400000")#include <iostream>#include <cstring>#include <cstdlib>#include <cstdio>#include <queue>#include <vector>#include <algorithm>#include <cmath>#include <map>#include <set>#include <stack>#include <string.h>//freopen ("in.txt" , "r" , stdin);using namespace std;#define eps 1e-8#define zero(_) (abs(_)<=eps)const double pi=acos(-1.0);typedef long long LL;const int Max=210;const int INF=1e9+7;struct point{ double x,y; void read() { scanf("%lf%lf",&x,&y); }} points[Max];double dist[Max][Max];int t=0;int n;double getdis(int i,int j){ return dist[(i+t)%n][(j+t)%n];}double getdist(int i,int j){ i=(i+n)%n; j=(j+n)%n; return sqrt((points[i].x-points[j].x)*(points[i].x-points[j].x)+ (points[i].y-points[j].y)*(points[i].y-points[j].y));}double ans[Max][Max][2];double dfs(int i,int j,int st){ i=(i+n)%n; if(!zero(ans[i][j][st])) return ans[i][j][st]; if(j==1) return ans[i][j][st]=getdis(i,i+(st?-1:1)); if(!st) return ans[i][j][st]=min(dfs(i+1,j-1,0)+getdis(i,i+1),dfs(i+j,j-1,1)+getdis(i,i+j)); else return ans[i][j][st]=min(dfs(i-1,j-1,1)+getdis(i,i-1),dfs(i-j,j-1,0)+getdis(i,i-j));}double solve(){ memset(ans,0,sizeof ans); return min(dfs(1,n-2,0)+getdis(0,1),dfs(n-1,n-2,1)+getdis(0,n-1));}int main(){ scanf("%d",&n); for(int i=0; i<n; i++) points[i].read(); for(int i=0; i<n; i++) for(int j=i; j<n; j++) { dist[i][j]=getdist(i,j); dist[j][i]=dist[i][j]; } double out=INF; out=min(out,solve()); for(int i=0; i<n-1; i++) { t++; point p=points[0]; for(int j=0; j<n-1; j++) points[j]=points[j+1]; points[n-1]=p; out=min(out,solve()); } printf("%.3f\n",out); return 0;}