hdu6219(最大空凸包)

题意:

  给一些点,求出一个最大的空凸包,这个凸包里没有任何给定点且要求这个凸包面积最大

分析:

  枚举凸包左下角的点,然后dp[i][j]表示凸包的最后两条边是j->i和i->O情况下凸包的面积最大值,这个是O(n^4)的

  可以利用凸性求个前缀和来完成O(1)的转移

  具体看这里:https://blog.csdn.net/nyroro/article/details/45268767

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=50;
 4 typedef int db;
 5 struct Point
 6 {
 7     /*点类*/
 8     db x,y;
 9     Point(){}
10     Point(db _x,db _y):x(_x),y(_y){}
11     void input()
12     {
13         scanf("%d%d",&x,&y);
14     }
15     Point operator + (const Point &t)const
16     {
17         return Point(x+t.x,y+t.y);
18     }
19     Point operator - (const Point &t)const
20     {
21         return Point(x-t.x,y-t.y);
22     }
23     db operator * (const Point &t)const
24     {
25         return x*t.y-y*t.x;
26     }
27     db len()const
28     {
29         return x*x+y*y;
30     }
31     bool operator < (const Point &t) const
32     {
33         if((*this)*t!=0) return (*this)*t>0;
34         return len()<t.len();
35     }
36 }p[maxn+5],a[maxn+5];
37 int n,m;
38 int ans;
39 int dp[maxn+5][maxn+5],sum[maxn+5][maxn+5];
40 void work(int n)
41 {
42     memset(dp,0,sizeof(dp));
43     memset(sum,0,sizeof(sum));
44     for(int i=2;i<=n;++i)
45     {
46         int j=i-1;
47         while(j>=1&&a[i]*a[j]==0) --j;
48         bool flag=0;
49         if(j==i-1) flag=1;
50         while(j>=1)
51         {
52             int k=j-1;
53             int res=a[j]*a[i];
54             while(k>=1&&(a[j]-a[i])*(a[k]-a[j])>0) --k;
55             if(k) res+=sum[j][k];
56             if(flag) dp[i][j]=res;
57             ans=max(ans,res);
58             j=k;
59         }
60         sum[i][1]=dp[i][1];
61         for(int j=2;j<i;++j) sum[i][j]=max(dp[i][j],sum[i][j-1]);
62     }
63 }
64 int main()
65 {
66     int T;
67     scanf("%d",&T);
68     while(T--)
69     {
70         scanf("%d",&n);
71         for(int i=1;i<=n;++i) p[i].input();
72         ans=0;
73         for(int i=2;i<=2;++i)
74         {
75             m=0;
76             for(int j=1;j<=n;++j) if(p[j].y>p[i].y||(p[i].y==p[j].y&&p[j].x>=p[i].x)) a[++m]=p[j]-p[i];
77             //for(int i=1;i<=m;++i) printf("%d %d\n",a[i].x,a[i].y);
78             //printf("\n");
79             sort(a+1,a+m+1);
80             //for(int i=1;i<=m;++i) printf("%d %d\n",a[i].x,a[i].y);
81             work(m);
82         }
83         //printf("%d\n",ans);
84         printf("%.1f\n",1.0*ans/2);
85     }
86     return 0;
87 }
View Code

 

posted @ 2018-05-06 11:49  Chellyutaha  阅读(687)  评论(0编辑  收藏  举报