hdu 1966 /poj 2066 Minimax Triangulation 计算几何

原文链接: hdu  poj



题目大意:给你n个点围城的多边形,顺时针或者逆时针给你,起始点任意,让你把他划成n-2个三角形,这些划法中最大的三角形的面积最小,输出这个最小值。

思路:按照区间长度进行DP。对于 i~j 这些点,考虑新加入的点是j,那么就多了两条弦 i~j,j-1 ~j,对于 i~j 这条弦,加进去,它能围成的是 Aea2(i,k,j),i<k<j,,此时最大的三角形是 max( Area2( i , k , j ) ,dp[ i ][ k ] ,dp[ k ][ j ] ),dp[ i ][ j ] 表示按照题目给的方向来的 i ~ j 的最小的面积,对于这些又取最小,就是dp[ i ][ j ] = min(max( Area2( i , k , j ) ,dp[ i ][ k ] ,dp[ k ][ j ] ),dp[ i ][ j ]),i<k<j,而同时,j - 1~j它围成的已经在dp[ k ][ j ] 之中包含了, 综合起来就是上面那个式子,长度从4开始DP,初始化为长度3的,为了统一,要把长度1、2的变成0,。这里还有一个关键的地方,那就是 Area2( i , k , j) 的时候,它有可能是凹多边形,要判断有没有出界,这个时候只要枚举除这三个点的全部的点,用面积和看看他们中间有没有点就行了。


#include<stdio.h>
#include<iostream>
#include<math.h>
#include<string.h>
using namespace std;
#define EPS 1e-8
#define Max 55
const int INF = (1 << 30);
int n;
double dp[Max][Max];

struct Point
{
    int x;
    int y;
}p[Max];



int Area2(Point p2, Point p3, Point p1)
{
    int temp = (p2.x - p1.x) * (p3.y - p1.y) - (p3.x - p1.x) * (p2.y - p1.y);
    return temp;
}

int check(int a, int b, int c)  //判断是否出界
{
    int area = fabs(Area2(p[a], p[b], p[c]));
    for (int i = 0; i < n; i++)
    {
        if (i == a || i == b || i == c)
        {
            continue;
        }
        int temp = fabs(Area2(p[a], p[b], p[i]))
                     + fabs(Area2(p[a], p[c], p[i])) + fabs(Area2(p[b], p[c], p[i]));
        if (temp == area)
        {
            return 0;
        }
    }
    return 1;
}


int main()
{
 freopen("E:\input.txt", "r", stdin);
    int num;
    scanf("%d", &num);
    while (num--)
    {
        scanf("%d", &n);
        for (int i = 0; i < n; i++)
        {
            scanf("%d%d", &p[i].x, &p[i].y);
        }
        memset(dp, 0, sizeof(dp));
        for (int i = 0; i < n; i++)
        {
            dp[i][(i + 2) % n] = fabs(Area2(p[i], p[(i + 1) % n], p[(i + 2) % n]));
        }
         for(int len = 3;len<=n;len++)
            {
                for(int i = 0;i<n;i++)
                {
                    int j = (i + len)%n;
                    dp[i][j] = INF;
                    for(int k = (i+1)%n; k!= j; k = (k+1)%n)
                    {
                        if(check(i,k,j)) dp[i][j] = min(dp[i][j],max(max(dp[i][k],dp[k][j]),fabs(Area2(p[i],p[k],p[j]))));
                    }
                    //printf("i = %d,j = %d,d = %f\n",i,j,d[i][j]);
                }
            }
        double ans = INF;
        for(int i = 0;i<n;i++)
            ans = min(dp[i][(i+n-1)%n],ans);
        printf("%.1f\n",ans/2);
    }

    return 0;
}


参考Blog:

UVALive 3132 Minimax Triangulation

poj 2066

ACM: 计算几何题 poj 2066





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值