• ●POJ 1259 The Picnic


    题链:

    http://poj.org/problem?id=1259

    题解:

    计算几何,凸包,DP

    题意:给出N($Nleq100$)个点,求出最大的凸包使得凸包里面不存在点(边上可以有)。输出最大凸包的面积。


    把所有点按x从小到大排序(若x相同则按y从小到大排序)。 

    依次枚举每个点p,把它作为凸包的左下角来计算此时可以形成的最大凸包。

    做法如下:

    将p号点作为原点,取出p+1~N的点(共m=N-p个点),对这m个点按极角逆时针排序。

    然后定义DP状态:

    f[j][i]:表示以i,j作为当前凸壳的最后两个点时的最大面积。(p<j<i)

    转移:(S(j,i,p)表示j,i,p三个点形成的三角形)

    f[j][i]=max(f[k][j])+S(j,i,p) (p<k<j且 $vec{kj} imesvec{ji}geq0$,即要形成凸壳)

    差不多就这样,然后注意细节就好了。(反正我是弄了好久才过样例的,233)

    复杂度 $O(N^4)$

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define MAXN 105
    #define INF 0x3f3f3f3f
    using namespace std;
    struct Point{
    	int x,y;
    	Point(int _x=0,int _y=0):x(_x),y(_y){}
    	void Read(){scanf("%d%d",&x,&y);}
    }D[MAXN],Q[MAXN];
    typedef Point Vector;
    bool operator == (Point A,Point B){return A.x==B.x&&A.y==B.y;}
    Vector operator - (Point A,Point B){return Vector(A.x-B.x,A.y-B.y);}
    int operator ^ (Vector A,Vector B){return A.x*B.y-A.y*B.x;}
    int operator * (Vector A,Vector B){return A.x*B.x+A.y*B.y;}
    int GL2(Vector A){//Get_Length^2
    	return A*A;
    }
    bool XYcmp(Point A,Point B){return A.x-B.x<0||(A.x-B.x==0&&A.y-B.y<0);}
    bool PAcmp(Point A,Point B){return (A^B)>0||((A^B)==0&&GL2(A)<GL2(B));}
    bool inTArea(Point P,Point A,Point B){//in_Triangle_Area
    	if(((B-A)^(P-A))<=0) return 0;
    	if((P^B)<=0||(P^A)>0) return 0;
    	return 1;
    }
    int F[MAXN][MAXN];
    int DP(int m){
    	int ret=0;
    	memset(F,0,sizeof(F));
    	for(int i=1;i<=m;i++)
    		for(int j=1;j<i;j++)
    			for(int k=j+1;k<i;k++){
    				if(Q[k]==Q[i]||Q[k]==Q[j]) continue;
    				if(!inTArea(Q[k],Q[j],Q[i])) continue;
    				F[j][i]=-INF;break;
    			}
    	for(int i=1;i<=m;i++)
    		for(int j=1;j<i;j++) if(!F[j][i]){
    			F[j][i]=Q[j]^Q[i]; int tmp=0;
    			for(int k=j-1;k;k--){
    				if(((Q[j]-Q[k])^(Q[i]-Q[j]))>=0) tmp=max(tmp,F[k][j]);
    				if(!(Q[k]^Q[j])) break;
    			}
    			F[j][i]+=tmp;
    			ret=max(ret,F[j][i]);
    		}
    	return ret;
    }
    int work(int n){
    	int m,ret=0;
    	sort(D+1,D+n+1,XYcmp);
    	for(int i=1;m=0,i<=n;i++){
    		for(int j=i+1;j<=n;j++) Q[++m]=D[j];
    		for(int j=1;j<=m;j++) Q[j]=Q[j]-D[i];
    		sort(Q+1,Q+m+1,PAcmp);
    		ret=max(ret,DP(m));
    	}
    	return ret;
    }
    int main(){
    	int Case,n; double ans;
    	for(scanf("%d",&Case);Case;Case--){
    		scanf("%d",&n);
    		for(int i=1;i<=n;i++) D[i].Read();
    		ans=1.0*work(n)/2;
    		printf("%.1lf
    ",ans);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    iOS开发--CoreGraphics简单绘图
    iOS开发--UITableView
    PowerDesigner
    使用jquery-qrcode生成二维码
    MVC中如何设置路由指定默认页
    项目管理
    版本管理
    如何在网页中嵌入百度地图
    asp.net网站中添加百度地图功能
    TCP/UDP简易通信框架源码,支持轻松管理多个TCP服务端(客户端)、UDP客户端
  • 原文地址:https://www.cnblogs.com/zj75211/p/8252489.html
Copyright © 2020-2023  润新知