uva 1331

原题:
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 ≤ 10000 and 0 ≤ y ≤ 10000.
Output
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.
Sample Input
1
6
7 0
6 2
9 5
3 5
0 3
1 1
Sample Output
9.0

中文:

给你一个多边形,多边形的顶点按照顺时针或逆时针的顺序给出。在这个多边形中连接不相交的的对角线将多边形分割成数个三角形,现在问你一种分割方法使得这个多边形被分割成数个三角形中,所有三角形中面积最大的三角形,面积最小。

代码:

#include<bits/stdc++.h>
//#include<mutex>
//#include<thread>
using namespace std;
const double eps = 1e-4;
const int maxn = 55;
const double inf =  0x7fffffff;
struct Point
{
    Point(double xx=0,double yy=0):x(xx),y(yy){}
    double x,y;
};

Point ps[maxn];
double dp[maxn][maxn];

int t,n;

double dist(int i,int j)
{
    return sqrt((ps[i].x-ps[j].x)*(ps[i].x-ps[j].x)+(ps[i].y-ps[j].y)*(ps[i].y-ps[j].y));
}
int dcmp(double x)
{
    if(fabs(x)<eps)
        return 0;
    else
        return x<0?-1:1;
}

int cross(const Point &a, const Point &b, const Point &p)
{
    return (b.x - a.x)*(p.y - a.y) - (b.y - a.y)*(p.x - a.x);
}


double area(int x, int y, int z)
{
    double ans;
    ans = (ps[x].x * ps[y].y + ps[y].x * ps[z].y + ps[z].x * ps[x].y - ps[x].x * ps[z].y - ps[y].x * ps[x].y - ps[z].x * ps[y].y) * 1.0 / 2;
    return abs(ans);
}



bool point_in_area(int x,int y,int z)
{
    double res = area(x,y,z);
    for(int i=1;i<=n;i++)
    {
        if(i != x && i != y && i !=z)
        {
            double sum = area(i,x,y)+area(i,x,z)+area(i,y,z);
            if(dcmp(sum-res)==0)
                return 0;
        }
    }
    return 1;
}

int main()
{
    ios::sync_with_stdio(false);
    cin>>t;
    while(t--)
    {
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            cin>>ps[i].x>>ps[i].y;
        }
        for(int i= n -2 ;i>=1;i--)
        {
            for(int j = i+2;j<=n;j++)
            {
                dp[i][j] = inf;
                for(int k = i+1;k<j;k++)
                {
                    if(point_in_area(i,j,k))
                        dp[i][j]=min(dp[i][j],max(area(i,j,k),max(dp[i][k],dp[k][j])));
                }
            }
        }
        cout<<fixed<<setprecision(1)<<dp[1][n]<<endl;
    }
	return 0;
}



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

解答:

紫书上的例题

算是最优三角形剖分问题的改进版本

原始的最优三角剖分问题是给定一个凸多边形,将凸多边形连接对角线使得将凸多边形三角剖分,每个三角形规定一个权重函数w(i,j,k),i,j,k对应三角形在凸多边形上的三个顶点。最后求三角形的权重和最优。

本题同样是对多边形进行三角剖分,不过不一定是凸多边形。这里在连接对角线划分三角形时,需要判断是否存在多边形中的点在连接的三角形当中。

本题要求的最优值是剖分后的最大三角形面积最小,如何表示状态。

d p [ i ] [ j ] dp[i][j] dp[i][j]表示按照某一个方向,第i个顶点到第j个顶点之间所形成的多边形的最优划分,即i到j表示的形成的多边形,三角剖分后得到的最大三角形最小面积。

如何描述状态转移?
原始的多边形三角剖分问题,进行状态转移很好理解,因为求解的子问题的最优值的“总和”就是该问题的最优值。

由于当前状态描述的子问题为i到j形成的多边形最大三角形面积最小,那么要想得到整个多边形的三角剖分最大的三角形面积最小,能否通过子问题所描述的最大三角形的最小面积得到结果?

答案是肯定的, d p [ i ] [ j ] dp[i][j] dp[i][j]描述的是第i个点到第j个点形成的多边形进行三角剖分得到的最大三角形的最小值,其子问题,假设 d p [ x ] [ y ] dp[x][y] dp[x][y] ( i < = x < y < = j i<=x<y<=j i<=x<y<=j)为所得到的第x个顶点到第y个顶点所形成的多边形的最大三角形的最小值。可以通过如下设置状态转移方程得到结果

d p [ i ] [ j ] = m i n ( d p [ i ] [ j ] , m a x ( a r e a ( i , j , k ) , m a x ( d p [ i ] [ k ] , d p [ k ] ) ) ) dp[i][j]=min(dp[i][j],max(area(i,j,k),max(dp[i][k],dp[k]))) dp[i][j]=min(dp[i][j],max(area(i,j,k),max(dp[i][k],dp[k])))
其中 a r e a ( i , j , k ) area(i,j,k) area(i,j,k)表示顶点i,j,k所形成的三角形

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值