uva 1331 Minimax Triangulation

给出一个多边形求三角分割使分割得到的最大三角形最小。可以是凹多边形,这一点比较坑~~

区间dp,跟最优三角剖分差不多,

状态转移:dp[j][j + i] = min(dp[j][j + i], max(max(dp[j][k], dp[k][j + i]), area(j, k, i + j)))

从j到j+i的分割得到的最大面积;

注意因为可以是凹多边形,所以会有一些不可以分割的情况,直接上代码吧(这里我没怎么懂,最后judge函数也是看了别人的,还是太水了)

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
const double INF = 1e20;
const double eps = 1e-6;
double dp[100][100];
int x[100], y[100], n;
void init() {
    for(int i = 0; i < 100; i++)
        for(int j =0; j < 100; j++)
            dp[i][j] = INF;
    for(int i = 0; i < 90; i++)
        dp[i][i] = dp[i][i + 1] = 0;
}
double area(int i, int j, int k) {
    double s = (double)(x[i] - x[j]) * (y[i] - y[k]) - (double)(y[i] - y[j]) * (x[i] - x[k]);
    s = fabs(s) / 2;
//    double s = square(dist(x[i], y[i], x[j], y[j]), dist(x[k], y[k], x[j], y[j]), dist(x[i], y[i], x[k], y[k]));
//    printf("%d %d %d %lf\n", i, j, k, s);
    return s;
}
bool judge (int a, int b, int c) {
    double cur = area(a, b, c);
    for (int i = 0; i < n; i++) {
        if (i == a || i == b || i == c)
            continue;
        double tmp = area(a, b, i) + area(b, c, i) + area(c, a, i);
        if (fabs(tmp - cur) < eps)
            return false;
    }
    return true;
}
int main() {
    int t, i, j, k;
    scanf("%d", &t);
    while(t--) {
        scanf("%d", &n);
        for(i = 0; i < n; i++)
            scanf("%d%d", &x[i], &y[i]);
        init();
        for(i = 0; i < n-2; i++) {
            dp[i][i + 2] = area(i, i + 1, i + 2);
        }
        for(i = 3; i < n; i++) {
            for(j = 0; j < n - i; j++) {
                for(k = j + 1; k < j + i; k++) {
                    if(judge(j, k, j + i))
                        dp[j][j + i] = min(dp[j][j + i], max(max(dp[j][k], dp[k][j + i]), area(j, k, i + j)));
                }
            }
        }
        printf("%.1lf\n", dp[0][n - 1]);
    }
    return 0;
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值