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對應三角形在凸多邊形上的三個頂點。最後求三角形的權重和最優。

本題同樣是對多邊形進行三角剖分,不過不一定是凸多邊形。這裏在連接對角線劃分三角形時,需要判斷是否存在多邊形中的點在連接的三角形當中。

本題要求的最優值是剖分後的最大三角形面積最小,如何表示狀態。

dp[i][j]dp[i][j]表示按照某一個方向,第i個頂點到第j個頂點之間所形成的多邊形的最優劃分,即i到j表示的形成的多邊形,三角剖分後得到的最大三角形最小面積。

如何描述狀態轉移?
原始的多邊形三角剖分問題,進行狀態轉移很好理解,因爲求解的子問題的最優值的“總和”就是該問題的最優值。

由於當前狀態描述的子問題爲i到j形成的多邊形最大三角形面積最小,那麼要想得到整個多邊形的三角剖分最大的三角形面積最小,能否通過子問題所描述的最大三角形的最小面積得到結果?

答案是肯定的,dp[i][j]dp[i][j]描述的是第i個點到第j個點形成的多邊形進行三角剖分得到的最大三角形的最小值,其子問題,假設dp[x][y]dp[x][y] (i<=x<y<=ji<=x<y<=j)爲所得到的第x個頂點到第y個頂點所形成的多邊形的最大三角形的最小值。可以通過如下設置狀態轉移方程得到結果

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])))
其中area(i,j,k)area(i,j,k)表示頂點i,j,k所形成的三角形

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章