题意:给你一个凸包,问遍历所有点一遍的最短路径
分析:由于图形是一个凸包,所以肯定是选一个点,然后从两端不断拓展出去,假设已经拓展[i , i+len ]这几个点,且f[ i ][ len ][0]为遍历这些点,且终点为i的最短路,f[ i ] [len] [1]为遍历这些点,且终点为i+len的最短路,那么有
f[i][len][0]=min(f[(i+1)%n][len-1][0]+d[i][(i+1)%n],
f[(i+1)%n][len-1][1]+d[i][(i+len)%n]);
f[i][len][1]=min(f[i][len-1][0]+d[(i+len)%n][i],
f[i][len-1][1]+d[(i+len)%n][(i+len-1)%n]);
也就是区间[i , i+len] 终点在i的情况,一定是从区间[i+1, i+len]转化过来的,就两种情况,从i+1到i, 或从+len 到i,另一种情况类似
然后注意下初始化就行了,说实话, 这题卡住了, 看了题解 = =
代码:
/** head files*/
#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <fstream>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <list>
#include <stdexcept>
#include <functional>
#include <utility>
#include <ctime>
using namespace std;
/** some operate*/
#define PB push_back
#define MP make_pair
#define REP(i,n) for(i=0;i<(n);++i)
#define FOR(i,l,h) for(i=(l);i<=(h);++i)
#define FORD(i,h,l) for(i=(h);i>=(l);--i)
#define MSET(arr,val) memset(arr,val,sizeof(arr))
#define MAX3(a,b,c) max(a,max(b,c))
#define MAX4(a,b,c,d) max(max(a,b),max(c,d))
#define MIN3(a,b,c) min(a,min(b,c))
#define MIN4(a,b,c,d) min(min(a,b),min(c,d))
/** some const*/
#define N 888
#define M 222222
#define PI acos(-1.0)
#define oo 1111111111
/** some alias*/
typedef long long ll;
/** Global variables*/
double f[N][N][2],d[N][N];
double x[N],y[N];
/** some template names, just push ctrl+j to get it in*/
//manacher 求最长回文子串
//pqueue 优先队列
//combk n元素序列的第m小的组合和
//pmatrix n个点的最大子矩阵
int main()
{
int i,j,len,n;
scanf("%d",&n);
REP(i,n)scanf("%lf%lf",&x[i],&y[i]);
REP(i,n)REP(j,n)
d[i][j]=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
REP(i,n)f[i][0][0]=f[i][0][1]=0;
FOR(len,1,n-1)
REP(i,n)
{
f[i][len][0]=min(f[(i+1)%n][len-1][0]+d[i][(i+1)%n],
f[(i+1)%n][len-1][1]+d[i][(i+len)%n]);
f[i][len][1]=min(f[i][len-1][0]+d[(i+len)%n][i],
f[i][len-1][1]+d[(i+len)%n][(i+len-1)%n]);
}
double ans=1e30;
REP(i,n)ans=MIN3(ans,f[i][n-1][0],f[i][n-1][1]);
printf("%.3lf\n",ans);
return 0;
}