zoukankan      html  css  js  c++  java
  • POJ1259 The Picnic 最大空凸包问题 DP

    POJ1259

    给定平面上100个点 求一个最大的凸包,使得它不包含其中任意点,且凸包的顶点是题目所给的点。

    枚举凸包左下角的点,顺时针枚举第二个点, 用opt[i][j]记录 i作为第二个点, 且第三个点k在向量i->j的右手(保持凸性)

    显然相邻的凸包可以用来转移, opt[j][h]可以加入opt[i][j]  大致思想就是这样 看Solve函数。

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    
    const int maxn=100;
    const double zero=1e-8;
    struct Vector
    {
     double x,y;	
    };
    
    inline Vector operator -(Vector a,Vector b)
    {
    	Vector c;
    	c.x=a.x-b.x;
    	c.y=a.y-b.y;
    	return c;
    }
    
    inline double sqr(double a)
    {
     return a*a;
    }
    
    inline int Sign(double a)
    {
     if(fabs(a)<=zero)return 0;
     return a<0 ? -1:1;
    }
    
    inline bool operator <(Vector a,Vector b)
    {
     return Sign(b.y-a.y)>0||Sign(b.y-a.y)==0&&Sign(b.x-a.x)>0;
    
    }
    
    inline double Max(double a,double b)
    {
     return a>b ? a:b;
    }
    
    inline double Length(Vector a)
    {
     return sqrt(sqr(a.x)+sqr(a.y));
    }
    
    inline double Cross(Vector a,Vector b)
    {
     return a.x*b.y-a.y*b.x;
    }
    
    Vector dot[maxn],List[maxn];
    double opt[maxn][maxn];
    int seq[maxn];
    int n,len;
    double ans;
    
    bool Compare(Vector a,Vector b)
    {
     int temp=Sign(Cross(a,b));
     if (temp!=0)return temp>0;
     temp=Sign(Length(b)-Length(a));
     return temp>0;
    }
    
    void Solve(int vv)
    {
     int t,i,j,_len;
     for(int ii=len=0;ii<n;ii++)
     	{
    	 if(dot[vv]<dot[ii])List[len++]=dot[ii]-dot[vv];
    	}
     for(i=0;i<len;i++)
     	for(j=0;j<len;j++)
     		opt[i][j]=0;
     sort(List,List+len,Compare);
     double v;
     for(t=1;t<len;t++)
     	{
     	 _len=0;
     	 for(i=t-1;i>=0&&Sign(Cross(List[t],List[i]))==0;i--);
     	 //cout<<i<<endl;
     	 while(i>=0)
     	 	{
     	 	 v=Cross(List[i],List[t])/2.;
     	 	 seq[_len++]=i;
     	 	 for(j=i-1;j>=0&&Sign(Cross(List[i]-List[t],List[j]-List[t]))>0;j--);
     	 	 if(j>=0)v+=opt[i][j];
     	 	 ans=Max(ans,v);
     	 	 opt[t][i]=v;
     	 	 i=j;
    		}
    	 for(i=_len-2;i>=0;i--)
    	    opt[t][seq[i]]=Max(opt[t][seq[i]],opt[t][seq[i+1]]);
    	}
    }
    
    int i;
    double Empty()
    {
     ans=0;
     for(i=0;i<n;i++)
     	Solve(i);
     return ans;
    }
    int main()
    {freopen("t.txt","r",stdin);
     int T;
     scanf("%d",&T);
     while(T--)
     	{
     	 scanf("%d",&n);
     	 for(int i=0;i<n;i++)
     	 	scanf("%lf%lf",&dot[i].x,&dot[i].y);
     	 printf("%.1lf
    ",Empty());
    	}
     return 0;
    }
    

      

  • 相关阅读:
    python .npy 存取 dict
    python 找零钱方案
    docker 容器里显示图形
    docker 安装vim
    软件测试基础知识
    Git命令——学习笔记2
    Git命令——学习笔记1
    Win10配置Git环境变量与基本使用
    Selenium Web自动化测试——基于unittest框架的PO设计模式
    Django+Celery学习笔记5——定时推送消息
  • 原文地址:https://www.cnblogs.com/heisenberg-/p/6891304.html
Copyright © 2011-2022 走看看