Uva 1331 - Minimax Triangulation(最优三角剖分 区间DP)

题目大意:按照顺时针或者逆时针的顺序给出多边的点,要将这个多边形分解成n-2个三角形,要求使得这些三角行中面积最大的三角形面积尽量小,求最小值。

思路:用区间DP可以很方便解决,多边形可能是凹边形,注意剖分的三角形必须在多边形内部,所以可以去掉剖分的三角形中包含其他点,但是其他的在多边形外部的三角形没想到其他方法去除,却ac了,不懂为何

//	Accepted	C++	0.042
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
#define inf 0x3f3f3f3f
const double esp = 1e-6;
int n;
struct point
{
    double x,y;

}poi[55];
double dp[55][55];
double area(point a,point b,point c)
{
    return fabs((b.x - a.x) * (c.y - a.y) - (c.x - a.x) * (b.y - a.y)) / 2.0 ;
}
bool judge(int a,int b,int c)
{
    for(int i = 1;i<=n;i++ )
    {
        if(i==a||i==b||i==c) continue;
        double s=area(poi[i],poi[a],poi[b])+area(poi[i],poi[b],poi[c])+area(poi[i],poi[c],poi[a]);
        if(fabs(s-area(poi[a],poi[b],poi[c]))<esp) return true;
    }
    return false;
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        memset(dp,0,sizeof(dp));
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%lf%lf",&poi[i].x,&poi[i].y);
        }
        for(int l=2;l<n;l++)
            for(int p=1;p+l<=n;p++)
            {
                dp[p][p+l]=inf;
                for(int k=p+1;k<p+l;k++)
                {
                    if(judge(p,k,p+l)) continue;
                    dp[p][p+l]=min(dp[p][p+l],max(max(dp[p][k],dp[k][p+l]),area(poi[p],poi[k],poi[p+l])) );
                }
            }
        printf("%.1f\n",dp[1][n]);
    }
    return 0;
}
时间: 2024-11-07 23:06:45

Uva 1331 - Minimax Triangulation(最优三角剖分 区间DP)的相关文章

uva 1331 - Minimax Triangulation(dp)

题目链接:uva 1331 - Minimax Triangulation 题目大意:按照顺时针或者逆时针的顺序给出多边的点,要将这个多边形分解成n-2个三角形,要求使得这些三角行中面积最大的三角形面积尽量小,求最小值. 解题思路:状态很好想,dp[i][j]表示从第i个点到第j个点,划分成j-i-1个三角形的最优解,然后每次转移时,枚举长度和左边界始点,那么根据长度和左边界点就可以知道右边界点,然后枚举左边界和右边界中间的点k,dp[i][j] = min(dp[i][j], max(max(

UVA 1331 Minimax Triangulation 区间DP

区间DP: 将一个多边形三角剖分,让可以得到的最大三角形的面积最小 dp[i][j]表示从i点到j点的最优值,枚举中间点k dp[i][j]=min(dp[i][j],max(area(i,j,k),max(dp[i][k],dp[k][j]))); 注意如果中间三角形i-j-k中有其他的点,这样的三角形是不可以剖分的 Minimax Triangulation Time Limit: 3000MS   Memory Limit: Unknown   64bit IO Format: %lld

1331 - Minimax Triangulation (区间DP+几何)

题目链接:1331 - Minimax Triangulation 题意:按顺序给定一些点,把这些点分割为n - 2个三角形,代价为最大三角形面积,求代价最小 思路:区间DP,dp[i][j]代表一个区间内,组成的情况,枚举k,dp[i][j] = min(max(dp[i][k],dp[k][j], area(i, j, k)),area代表i.j.k三点构成的三角形面积,然后判断该三角形内有没其他点即可 代码: #include <stdio.h> #include <string.

UVa 1331 最大面积最小的三角剖分

https://vjudge.net/problem/UVA-1331 题意:输入一个多边形,找一个最大三角形面积最小的三角剖分,输出最大三角形的面积. 思路: 最优三角剖分. dp[i][j]表示从i点到j点的最优值,枚举中间点k. 转移方程为dp[i][j]=min(dp[i][j],max(area(i,j,k),max(dp[i][k],dp[k][j]))). 如果三角形i-j-k中有其他的点,是不可以剖分的,需要去检验一下. 可以看一下大神的题解,写得很详细.http://www.c

uva 10304 Optimal Binary Search Tree (区间DP)

uva 10304 Optimal Binary Search Tree 题目大意:给出N个结点(已知每个结点的权值)来建树,建树时要满足以下规则:左子树的节点的值要全小于父节点,右子树的节点的值要全大于父节点.要求最后建出的树总权值最小.总权值=各结点乘以层数(从0层开始)之后相加的和. 解题思路:dp[i][j]代表区间第i个结点到第j个结点组成的树最小的总权值.dp[j][i]=min(dp[j][i],dp[j][k?1]+dp[k+1][i]+sum[i]?sum[j?1]?num[k

uva 10529 - Dumb Bones(概率+区间dp)

题目连接:uva 10529 - Dumb Bones 题目大意:给定n,表示要放n个骨牌,每次放下骨牌,有可能向左倒的概率为pl,向右倒的概率为pr,如果倒下,会将那一侧的骨牌全部推倒,可以选择位置先后放骨牌,问说一种放骨牌次数最少的期望是多少. 解题思路:dp[i]表示放i个骨牌需要的步数期望,维护一个最优放的位置,dp[i] = min\{ (从i-1到i的步数)} + (0到i-1的步数)} (从i-1到i的步数):dp[i?j?1]?pl+dp[j]?pr+11?pl?pr (0到i-

UVA 10003 Cutting Sticks 区间DP+记忆化搜索

UVA 10003 Cutting Sticks+区间DP 纵有疾风起 题目大意 有一个长为L的木棍,木棍中间有n个切点.每次切割的费用为当前木棍的长度.求切割木棍的最小费用 输入输出 第一行是木棍的长度L,第二行是切割点的个数n,接下来的n行是切割点在木棍上的坐标. 输出切割木棍的最小费用 前话-区间dp简单入门 区间dp的入门下面博客写的非常好,我就是看的他们博客学会的,入门简单,以后的应用就得靠自己了. https://blog.csdn.net/qq_41661809/article/d

uva 10003 Cutting Sticks 简单区间dp

// uva 10003 Cutting Sticks 区间dp // 经典的区间dp // dp(i,j)表示切割小木棍i-j所需要的最小花费 // 则状态转移为dp(i,j) = min{dp(i,k) + dp(k,j) + a[j]-a[i]) // 其中k>i && k<j // a[j] - a[i] 为第一刀切割的代价 // a[0] = 0,a[n+1] = L; // dp数组初始化的时候dp[i][i+1]的值为 0,这表示 // 每一段都已经是切割了的,不

uva live 3516 Exploring Pyramids 区间DP

// uva live 3516 Exploring Pyramids 区间DP // // 题目大意: // // 给你一个多叉树,每个节点是一个大写字母,从根节点走,按照先序遍历的 // 原则访问,不能访问则回溯,每次记录一下节点的字符,最后得到一个字符串.现 // 在给你一个字符串,问可能符合条件的多叉树的数量. // // 解题思路: // // 区间DP,我们注意到,从根节点出发,一定会再次回到根节点,那么我们可以设 // d(i,j) 是序列i到j段形成的符合条件的多叉树的数量,则