1 条题解
-
0
#include<bits/stdc++.h> using namespace std; #define N 2005 int n,m,k,s,t; long double x[N],y[N],f[N][N][2]; int g[N][N][2],a[N],tmp,tot,_k; int mi(long double &a,long double b){ return (a>b?(a=b,1):0); } long double dist(int a,int b){ return sqrt((x[a]-x[b])*(x[a]-x[b])+(y[a]-y[b])*(y[a]-y[b])); } int main() { cin>>n; for (int i=1;i<=n;++i){ cin>>x[i]>>y[i]; if (k==0 || y[i]>y[k]) k=i; } _k=k+n; for (int i=1;i<=n;++i) //原序列倍长 x[i+n]=x[i],y[i+n]=y[i]; for (int i=1;i<=2*n;++i)//初始化 for (int j=i;j<=i+n-1;++j) f[i][j][0]=f[i][j][1]=1e18; f[k][k][0]=f[k][k][1]=f[_k][_k][0]=f[_k][_k][1]=0; for (int l=1;l<=n-1;++l)//区间dp,优先枚举长度 for (int i=1;i<=n;++i){//算出左右端点位置 int j=i+l; if (mi(f[i][j][0],f[i+1][j][0]+dist(i,i+1))) g[i][j][0]=0; if (mi(f[i][j][0],f[i+1][j][1]+dist(i,j))) g[i][j][0]=1; if (mi(f[i][j][1],f[i][j-1][0]+dist(j,i))) g[i][j][1]=0; if (mi(f[i][j][1],f[i][j-1][1]+dist(j,j-1))) g[i][j][1]=1; } long double ans=1e18; for (int i=1;i<=n;++i){ if (mi(ans,f[i][i+n-1][0])) s=i,tmp=0; if (mi(ans,f[i][i+n-1][1])) s=i,tmp=1; } t=s+n-1; while (s<=t){//还原路径 if (tmp==0) a[++tot]=s,tmp=g[s][t][tmp],++s; else a[++tot]=t,tmp=g[s][t][tmp],--t; } for (int i=tot;i>=1;--i) cout<<(a[i]>n?a[i]-n:a[i])<<' '; }
- 1
信息
- ID
- 298
- 时间
- 1000ms
- 内存
- 1024MiB
- 难度
- 2
- 标签
- 递交数
- 30
- 已通过
- 23
- 上传者