【最大空凸包 模板 计算几何 + DP】HDU - 6219 J - Empty Convex Polygons

J - Empty Convex Polygons HDU - 6219 

Given a set of distinct points S on a plane, we define a convex hole to be a convex polygon having any of thegiven points as vertices and not containing any of the given points in its interior. In addition to the vertices, other given points may lie on the perimeter of the polygon. We want to find a convex hole as above forming the convexpolygon with the largest area. 

Input

This problem has several test cases. 
The first line of input contains an integer t (1 ≤ t ≤ 100) indicating the total number of cases. For each test case,the first line contains the integer n (3 ≤ n ≤ 50). Each of the following n lines describes a point with two integers x and y where -1000 ≤ x, y ≤ 1000. 
We guarantee that there exists at least one non-degenerated convex polygon. 

Output

For each test case, output the largest area of empty convex polygon, with the precision of 1 digit. 
Remark: The corollary of Pick’s theorem about the polygon with integer coordinates in that says the area of it iseither ends to .0 or .5.

Sample Input

4
3
0 0
1 0
0 1
5
0 0
1 0
2 0
0 1
1 1
5
0 0
3 0
4 1
3 5
-1 3
6
3 1
1 0
2 0
3 0
4 0
5 0

Sample Output

0.5
1.5
17.0
2.0

T组测试数据,每组n个点

求出n个点以其中若干个点为顶点的最大凸多边形面积,要求多边形内部不能有其它点

复杂度O(n^3)

思路:枚举凸包的左下角点,然后DP找出以这个点为起始位置能构成的最大空凸包面积,最后取这些空凸包面积的最大值为答案。DP过程:假设当前点OO为左下角,dp[i][j]dp[i][j]表示得是以OiOi,ijij为凸包的最后两条边所构成的凸包面积的最大值。状态转移方程:dp[i][j]=max(dp[i][j],triangle(O,i,j)+dp[j][k])dp[i][j]=max(dp[i][j],triangle(O,i,j)+dp[j][k])。时间复杂度:O(n4)

参考:

https://blog.csdn.net/Jaihk662/article/details/81988607

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
#include<string>
#include<math.h>
#include<queue>
#include<stack>
#include<iostream>
using namespace std;
#define LL long long
#define mod 1000000007
typedef struct Point
{
	int x, y;
	Point() {}
	Point(int x, int y): x(x),y(y) {}
	Point operator + (const Point &b) const {  return Point(x+b.x,y+b.y);  }
	Point operator - (const Point &b) const {  return Point(x-b.x,y-b.y);  }
	int operator * (const Point &b) const {  return x*b.y-y*b.x;  }
	int len() const {  return x*x+y*y;  }
	int operator < (const Point &a) const
	{
		if((*this)*a>0 || (*this)*a==0 && len()<a.len())
			return 1;
		return 0;
	}
}Point;
int n;
Point s[122], p[122];
int dp[122][122];
int Jud(int m)
{
	int ans, i, j, now, k, flag, S;
	memset(dp, 0, sizeof(dp));
	ans = 0;
	for(i=2;i<=m;i++)
	{
		now = i-1;
		while(now>=1 && p[i]*p[now]==0)
			now--;
		flag = 0;
		if(now==i-1)
			flag = 1;
		while(now>=1)
		{
			S = p[now]*p[i];
			k = now-1;
			while(k>=1 && (p[now]-p[i])*(p[k]-p[now])>0)
				k--;
			if(k>=1)
				S += dp[now][k];
			if(flag)
				dp[i][now] = S;
			ans = max(ans, S);
			now = k;
		}
		if(flag==0)
			continue;
		for(j=1;j<=i-1;j++)
			dp[i][j] = max(dp[i][j],dp[i][j-1]);
	}
	return ans;
}
int main(void)
{
	int T, i, j, m, ans;
	scanf("%d", &T);
	while(T--)
	{
		scanf("%d", &n);
		for(i=1;i<=n;i++)
			scanf("%d%d", &s[i].x, &s[i].y);
		ans = 0;
		for(i=1;i<=n;i++)
		{
			m = 0;
			for(j=1;j<=n;j++)
			{
				if(s[j].y>s[i].y || s[j].y==s[i].y && s[j].x>=s[i].x)
					p[++m] = s[j]-s[i];
			}
			sort(p+1, p+m+1);
			ans = max(ans, Jud(m));
		}
		printf("%.1f\n", ans/2.0);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41037114/article/details/82946752
今日推荐