• Gym-102576H Lighthouses


    题目传送门

    分析:
    把凸多边形简化成一个圆,一次电车游览会把圆分割成两部分,之后只能在其中一部分里面进行游览
    考虑DP,设(F_{i,j,0/1})表示,目前我们只能游览逆时针方向((i,j))中的点,并且下一步是从(i)还是(j)出发
    枚举区间中的某个点(k),分类讨论,简单转移

    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<queue>
    
    #define maxn 305
    #define eps 1e-7
    
    using namespace std;
    
    inline int getint()
    {
    	int num=0,flag=1;char c;
    	while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;
    	while(c>='0'&&c<='9')num=num*10+c-48,c=getchar();
    	return num*flag;
    }
    
    int n,m;
    struct node{
    	double x,y;
    }p[maxn];
    double dis[maxn][maxn],f[maxn][maxn][2];
    inline double getdis(node x,node y)
    {return sqrt(pow(x.x-y.x,2)+pow(x.y-y.y,2));}
    
    int main()
    {
    	int T=getint();
    	while(T--)
    	{
    		memset(dis,0,sizeof dis),memset(f,0,sizeof f);
    		n=getint();
    		for(int i=0;i<n;i++)p[i].x=getint(),p[i].y=getint();
    		m=getint();
    		for(int i=1;i<=m;i++)
    		{
    			int u=getint()-1,v=getint()-1;
    			dis[u][v]=dis[v][u]=getdis(p[u],p[v]);
    			f[u][v][0]=f[v][u][0]=f[u][v][1]=f[v][u][1]=dis[u][v];
    		}
    		for(int d=n-1;d;d--)for(int i=0;i<n;i++)
    		{
    			int j=(i+d)%n;
    			for(int k=(i+1)%n;k!=j;k=(k+1)%n)
    			{
    				if(dis[k][j]>0)
    				{
    					f[i][k][1]=max(f[i][k][1],f[i][j][1]+dis[k][j]);
    					f[k][j][0]=max(f[k][j][0],f[i][j][1]+dis[k][j]);
    				}
    				if(dis[i][k]>0)
    				{
    					f[i][k][1]=max(f[i][k][1],f[i][j][0]+dis[k][i]);
    					f[k][j][0]=max(f[k][j][0],f[i][j][0]+dis[k][i]);
    				}
    			}
    		}
    		double ans=0;
    		for(int i=0;i<n;i++)for(int j=0;j<n;j++)ans=max(ans,max(f[i][j][0],f[i][j][1]));
    		printf("%.10lf
    ",ans);
    	}
    }
    

  • 相关阅读:
    作业
    作业4
    作业1
    作业
    补交课堂作业
    补交最后一题
    第三次作业
    作业
    C语言 homework(4)
    C语言 homework (3)
  • 原文地址:https://www.cnblogs.com/Darknesses/p/13198478.html
Copyright © 2020-2023  润新知