[UVA1331]最大面积最小三角形剖分

Triangulation of surfaces has applications in the Finite Element Method of solid mechanics. Theobjective is to estimate the stress and strain on complex objects by partitioning them into small simpleobjects which are considered incompressible. It is convenient to approximate a plane surface with asimple polygon, i.e., a piecewise-linear, closed curve in the plane on m distinct vertices, which doesnot intersect itself. A chord is a line segment between two non-adjacent vertices of the polygon whichlies entirely inside the polygon, so in particular, the endpoints of the chord are the only points of thechord that touch the boundary of the polygon. A triangulation of the polygon, is any choice of m − 3chords, such that the polygon is divided into triangles. In a triangulation, no two of the chosen chordsintersect each other, except at endpoints, and all of the remaining (unchosen) chords cross at least oneof the chosen chords. Fortunately, finding an arbitrary triangulation is a fairly easy task, but what ifyou were asked to find the best triangulation according to some measure?

Figure I.1: Five out of nine possible triangulations of the example polygon. The leftmost has thesmallest largest triangle.

Input

On the first line of the input is a single positive integer n, telling the number of test scenarios to follow.Each scenario begins with a line containing one positive integer 2 < m < 50, being the number ofvertices of the simple polygon. The following m lines contain the vertices of the polygon in the orderthey appear along the border, going either clockwise or counter clockwise, starting at an arbitraryvertex. Each vertex is described by a pair of integers x y obeying 0 ≤ x ≤ 10000 and 0 ≤ y ≤ 10000.

OutputFor each scenario, output one line containing the area of the largest triangle in the triangulation ofthe polygon which has the smallest largest triangle. The area should be presented with one fractionaldecimal digit.

Sample Input

1

6

7 0

6 2

9 5

3 5

0 3

1 1

Sample Output

9.0


题意:

输入一个简单n(2<n<50)边形,找一个最大三角形面积最小的三角形剖分,输出最大三角形的面积。


题解:

此题有些类似石子合并
dp[i][j]表示编号从i到j的点构成的多边形中的最大三角形面积
dp[i][j]=max{ dp[i][k], dp[k][j], S(i,j,k) } ;
注意到这一点,这个图是封闭的,也就是一个环状,所以不能忽略掉如dp[n][1]这种情况 
对于凹多边形,要判断三角形是否存在,可以转化成是否有点在三角形的内部,若存在,此三角形就不存在


#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<algorithm>
using namespace std;
const double INF=1e40;
const double eps=1e-7;
const int N=55;
int T, n;
struct node{ double x, y; }p[N];
double dp[N][N];
 
double S(int a, int b, int c) {  
    return fabs(0.5*(p[a].x*(p[b].y - p[c].y) + p[b].x*(p[c].y - p[a].y) + p[c].x*(p[a].y - p[b].y)));  
}

bool Judge( int a, int b, int c ) {//考虑凹多边形的情况, 如果在三角形内部有点,那么它与其他三个点形成的三个三角形面积之和等于这个三角形的面积
	for( int i=1; i<=n; i++ ) {
		if( i==a || i==b || i==c ) continue;
		double summ=S( a, b, i )+S( a, c, i )+S( b, c, i );
		if( fabs(summ-S( a, b, c ))<eps ) return 0;
	}
	return 1;
}

int main() {
	for( scanf( "%d", &T ); T; T-- ) {
		scanf( "%d", &n );
		for( int i=1; i<=n; i++ )
			scanf( "%lf%lf", &p[i].x, &p[i].y );
			
		memset( dp, 0, sizeof dp );
		
		for( int len=3; len<=n; len++ )
			for( int i=1; i<=n; i++ ) {
				int j=i+len-1; 
				if( j>n ) break;
				dp[i][j]=INF;
				for( int k=i+1; k<=j-1; k++ )
					if( Judge( i, j, k ) )
						dp[i][j]=min( dp[i][j], max( S( i, k, j ), max( dp[i][k], dp[k][j] ) ) );
			}
		printf( "%.1lf\n", dp[1][n] );
	}
	return 0;
}


也可以用海伦公式 ,但因为精度问题wa了。下附一小段代码:

double length( node a, node b ) {
	double xx=( a.x-b.x )*( a.x-b.x );
	double yy=( a.y-b.y )*( a.y-b.y );
	return sqrt( xx+yy );
}

double S( int i, int k, int j ) {
	double a=length( p[i], p[k] );
	double b=length( p[i], p[j] );
	double c=length( p[k], p[j] );
	double p=( a+b+c )/2;
	return sqrt( p*(p-a)*(p-b)*(p-c) );
}



关于求三角形面积的方法,详见:http://blog.csdn.net/uisg103/article/details/76095884


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值