hznu 1139: Minimax Triangulation(dp,三角形面积模板)

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?

输入

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.

输出

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

样例输入

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

样例输出

9.0
http://hsacm.cn/JudgeOnline/problem.php?id=1139

//按顺时针或逆时针给你一个m边形
//将它分成m-2个三角形,使得三角形中最大的面积最小 
//求这个面积(注意分割线不能相交) 
//dp[i][j]表示顶点i到顶点j的最大三角的最小面积
#include<iostream>
#include<algorithm>
#include<string>
#include<string.h>
#include<cmath>
#include<queue>
#include<stdlib.h>
#include<map>
#include<vector>
#include<cstdio>
#define INF 1e9
#define ll long long
using namespace std;
struct node  {  
    int x,y;  
}point[51];  
int t,n;
double dp[51][51];  
int multiply(int a,int b){  
    return point[a].x*point[b].y-point[a].y*point[b].x;  
}  
double area(int a,int b,int c){ //已知三点求三角形面积的模板 
    int ret=multiply(a,b)+multiply(b,c)+multiply(c,a);  
    if(ret>0)  
      return ret/2.0;  
    else 
      return -ret/2.0;  
}  
bool judge(int a,int b,int c){  
    double ret=area(a,b,c);  
    for(int p=1;p<=n;p++){  
        if(p==a||p==b||p==c)  
          continue;  
        if(ret==area(a,b,p)+area(a,c,p)+area(b,c,p))//有其他点在这个三角形内,不符合【分割线不相交】 
          return false;  
    }  
    return true;  
}  
int main(){  
    scanf("%d",&t);  
    while(t--){  
        scanf("%d",&n);  
        for(int i=1;i<=n;i++)  
           scanf("%d%d",&point[i].x,&point[i].y);  
        for(int i=1;i<=n-2;i++)  
           dp[i][i+2]=area(i,i+1,i+2);  
        for(int p=3;p<n;p++){
           for(int i=1;i+p<=n;i++){  
               int j=i+p;  
               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(area(i,k,j),max(dp[i][k],dp[k][j]))); 
               }
           }  
       }
        printf("%.1f\n",dp[1][n]);  
    }  
    return 0;
}  


你可能感兴趣的:(hznu 1139: Minimax Triangulation(dp,三角形面积模板))