1 条题解

  • 0
    @ 2023-7-19 11:25:47

    image image image

    #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
    上传者