紫书第九章-----动态规划初步(最优三角剖分,例题9-11 Minimax Triangulation UVA - 1331 )

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ccnuacmhdu/article/details/81507092

最优三角剖分

《算法竞赛入门经典(第2版)》讲解如下:
三角剖分是指用不相交的对角线把一个多边形分成若干个三角形。
这里写图片描述
这里写图片描述

例题9-11 Minimax Triangulation UVA - 1331

本题就是三角剖分的一个典型例题,求的是最大三角形的面积中,面积最大的三角形的面积最小的三角剖分所对应的这个最大的三角形面积。这道题需要注意的地方是,因为题目给出的图形不一定是凸多边形,参考上面的动态规划思路并结合题图可知,i-j可能不是多边形的对角线!
这里写图片描述

状态:d[i][j]表示顶点i,i+1,…,j-1,j形成的多边形的最优解
状态转移:d[i][j]=min{d[i[[j],max{d[i][k],d[k][j],s(i,j,k)}}

如上图所示多边形,当i=A,j=B,k=C时,这个三角形中包含多边形的一个顶点D,这是不合乎三角剖分的,并且这个三角形会影响最优解。另外,还有一种情况,当i=C,j=E,k=D时候,也是不合乎三角剖分的,但是这个三角形不可能是最优解,即他不会影响最优解,所以不必专门考虑此种情况了,只考虑包含多边形一个顶点的情形即可。
这里写图片描述
这里写图片描述
代码参考地址

#include<iostream>
#include<cmath>
#include<cstring>
#include<iomanip>
using namespace std;

const double INF=10e9;
const int maxn=55;
int n;
int m;
int x[maxn],y[maxn];
double d[maxn][maxn];

double dis(int i,int j){
    return sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
}

//海伦-秦九韶公式,已知三点坐标求三角形面积
double area(int i,int j,int k){
    double a=dis(i,j),b=dis(i,k),c=dis(j,k);
    double p=(a+b+c)/2.0;
    return sqrt((p-a)*(p-b)*(p-c)*p);
}

bool check(int i,int j,int k){
    for(int a=1;a<=m;a++){
        if(i==a || j==a || k==a) continue;
        double tmp=area(i,j,a)+area(i,k,a)+area(j,k,a)-area(i,j,k);
        if(tmp<0) tmp=-tmp;
        if(tmp<0.001) return false;
    }
    return true;
}

int main()
{
    cin>>n;
    while(n--){
        cin>>m;
        for(int i=1;i<=m;i++){
            cin>>x[i]>>y[i];
        }
        memset(d,0,sizeof(d));
        for(int i=m;i>=1;i--){
            for(int j=i+2;j<=m;j++){
                d[i][j]=INF;
                for(int k=i+1;k<=j-1;k++){
                    if(check(i,j,k)){
                        d[i][j]=min(d[i][j],max(max(d[i][k],d[k][j]),area(i,j,k)));
                    }
                }
            }
        }
        cout<<fixed<<setprecision(1)<<d[1][m]<<endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/ccnuacmhdu/article/details/81507092
今日推荐