UVA 1331 Minimax Triangulation 区间DP


区间DP: 将一个多边形三角剖分,让可以得到的最大三角形的面积最小


dp[i][j]表示从i点到j点的最优值,枚举中间点k

dp[i][j]=min(dp[i][j],max(area(i,j,k),max(dp[i][k],dp[k][j])));

注意如果中间三角形i-j-k中有其他的点,这样的三角形是不可以剖分的


Time Limit: 3000MS Memory Limit: Unknown 64bit IO Format: %lld & %llu

 Status

Description

Download as PDF

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

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 of vertices of the simple polygon. The following m lines contain the vertices of the polygon in the order they appear along the border, going either clockwise or counter clockwise, starting at an arbitrary vertex. Each vertex is described by a pair of integers x y obeying 0 ≤ x ≤ 10 000 and 0 ≤ y ≤ 10 000.

Output 

For each scenario, output one line containing the area of the largest triangle in the triangu-lation of the polygon which has the smallest largest triangle. The area should be presented with one fractional decimal digit.

Sample Input 

1
6
7 0
6 2
9 5
3 5
0 3
1 1

Sample Output 

9.0

Source

Root :: AOAPC II: Beginning Algorithm Contests (Second Edition) (Rujia Liu) :: Chapter 9. Dynamic Programming ::  Examples
Root :: AOAPC I: Beginning Algorithm Contests -- Training Guide (Rujia Liu) :: Chapter 1. Algorithm Design :: Dynamic Programming ::  Exercises: Intermediate

 Status



/* ***********************************************
Author        :CKboss
Created Time  :2015年02月12日 星期四 16时24分21秒
File Name     :UVA1331.cpp
************************************************ */

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstdlib>
#include <vector>
#include <queue>
#include <set>
#include <map>

using namespace std;

const int maxn=60;
const double INF = 1LL<<30; 
const double eps = 1e-7;

struct Point
{
	double x,y;
	Point(double _x=0,double _y=0):x(_x),y(_y){};
}pt[maxn];

double Area(int a,int b,int c)
{
	Point A=pt[a],B=pt[b],C=pt[c];
	return fabs((B.x-A.x)*(C.y-A.y)-(C.x-A.x)*(B.y-A.y))*0.5;
}

int n;
double dp[maxn][maxn];

double dfs(int l,int r)
{
	if(r==l+1) return dp[l][r]=0;
	if(dp[l][r]>eps) return dp[l][r];

	double temp=INF;
	for(int k=l+1;k<r;k++)
	{
		/// 检查三角形 l-k-r 是否可被剖分
		bool flag=true;
		double area=Area(l,k,r);
		for(int i=0;i<n&&flag;i++)
		{
			if(i==l||i==k||i==r) continue;
			double suma=Area(l,k,i)+Area(l,r,i)+Area(k,r,i);
			if(fabs(area-suma)<eps) flag=false;
		}
		if(flag) 
			temp=min(temp,max(area,max(dfs(l,k),dfs(k,r))));
	}
	return dp[l][r]=temp;
}

int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);

	int T_T;
	scanf("%d",&T_T);
	while(T_T--)
	{
		scanf("%d",&n);
		for(int i=0;i<n;i++)
		{
			double a,b;
			scanf("%lf%lf",&a,&b);
			//pt[i]=(Point){a,b};
			pt[i].x=a; pt[i].y=b;
		}
		for(int i=0;i<=n;i++) for(int j=0;j<=n;j++) dp[i][j]=-9;
		dfs(0,n-1);
		printf("%.1lf\n",dp[0][n-1]);
	}
    
    return 0;
}



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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值