【UVA1331】关于最优三角剖分
最近在练习DP专题,学会了很多表示方法和转换方法,今天做最优三角剖分的时候发现脑子卡了,不会表示状态,于是写个博客记录一下。
最优三角剖分的一类题目都是差不多的。给你一个多边形,让你把它分割成若干个三角形,求三角形某最优解,比如UVA1331要求面积最大的三角形的面积最小。如图是各种切割方法:

不知道一开始看到最大值最小化会不会又一下子想到枚举答案二分去了呢,不过本题正解是DP。
然而,这题最难的地方不是推出递推方程,而是表示状态。因为如果允许随意切割,则“半成品”多边形的各个定点是可以在原多边形中随意选取的。这就是我一直在纠结的一个问题,比如下面的第一张图(除起始点和结束点,相邻的点编号都是连续的):

一共有4条边,我们可以以随意的顺序切割,不过如果这样的话,就会出现类似v0v3v4v6这样的多边形,这样的多边形很难用简洁的状态表示出来,这就是让我一开始很纠结的地方。
其实我们会发现,对于同一种切割方法,我们可以有多种切割顺序,但我们只要计算一种就好了,不如把决策顺序规范化。例如还是上面第一张图,我们可以先切割出三角形v0v3v6,那么我们切割完之后可以把图分割成一个三角形和两个多边形,而组成这两个个多边形的点的编号都是连续的。
于是我们可以得出一种切割方法,比如我要切割多边形i,i+1,...,j-1,j(i<j),那么我下一步切割的三角形一定有i和j这两个点(这样的规定并不会出错,因为无论我们如何切割,分出来的三角形中一定有一个过i和j),而这样的切割方法的优点是保证了每次切出来的多边形组成的点的编号都是连续的,于是我们就可以用两个元素表示一个多边形的状态了,这样dp转移方程很容易可以得出来:
d(i,j)=min{max(d(i,k),d(k,j),S(i,j,k))|i<k<j};
其中,S(i,j,k)为三角形i-j-k的面积。不过此时需要保证i-j是对角线(唯一的例外是i=0且j=n-1),具体做法是当边i-j不满足条件时直接设为INF,其他部分和凸多边形的情形完全一样。
代码如下:
#include<cstdio>
#include<cstdlib>
#define INF 0xfffffff const int Maxm=+; int m;
int x[Maxm],y[Maxm];
double d[Maxm][Maxm]; double area(int a,int b,int c)
{
double s=(double)(1.0/)*(x[a]*y[b]+x[b]*y[c]+x[c]*y[a]-x[a]*y[c]-x[b]*y[a]-x[c]*y[b]);
if(s<) return -s;
return s;
} double mymin(double a,double b) {return a<b?a:b;} double mymax(double a,double b) {return a>b?a:b;} bool check(int a,int b,int c)
{
int i;
for(i=;i<=m;i++)
{
if(i==a||i==b||i==c) continue;
double d=area(a,b,i)+area(a,c,i)+area(b,c,i)-area(a,b,c);
if(d<) d=-d;
if(d<=0.01) return ;
}
return ;
} int main()
{
int n;
scanf("%d",&n);
while(n--)
{
int i,j,k;
scanf("%d",&m);
for(i=;i<=m;i++) scanf("%d%d",&x[i],&y[i]);
for(i=m;i>=;i--)
{
d[i][i+]=0.0;
for(j=i+;j<=m;j++)
{
d[i][j]=INF;
for(k=i+;k<j;k++)
{
if(check(i,j,k))
d[i][j]=mymin(d[i][j],mymax(mymax(area(i,j,k),d[i][k]),d[k][j]));
}
} }
printf("%.1lf\n",d[][m]);
}
}
ps:给定三个点求面积最好用叉积,而如果知道三条边求面积用海伦公式。
20:19:34
【UVA1331】关于最优三角剖分的更多相关文章
- (DP) 关于最优三角剖分
https://www.cnblogs.com/Konjakmoyu/p/4905563.html 这个人写的好 最优三角剖分的核心思想: 确定决策顺序. 有时一个解可以用许多决策顺序得出, 这时候我 ...
- Ex 6_12 凸多边形的最优三角剖分..._第六次作业
假设顶点的总数为n,从0到n-1. 从序号为0的顶点开始以逆时针方向排序,对于 令子问题A[i,j]为包含顶点i,i+1, . . . j的凸多边形的最小三角剖分代价,dist(i,j)为顶点i到顶点 ...
- UVA - 1331 Minimax Triangulation (区间dp)(最优三角剖分)
题目链接 把一个多边形剖分成若干个三角形,使得其中最大的三角形面积最小. 比较经典的一道dp问题 设dp[l][r]为把多边形[l,r]剖分成三角形的最大三角形面积中的最小值,则$dp[l][r]=m ...
- ZOJ - 3537 Cake (凸包+区间DP+最优三角剖分)
Description You want to hold a party. Here's a polygon-shaped cake on the table. You'd like to cut t ...
- Uva 1331 - Minimax Triangulation(最优三角剖分 区间DP)
题目大意:依照顺时针或者逆时针的顺序给出多边的点,要将这个多边形分解成n-2个三角形,要求使得这些三角行中面积最大的三角形面积尽量小,求最小值. 思路:用区间DP能够非常方便解决,多边形可能是凹边形, ...
- UVa 1331 最大面积最小的三角剖分
https://vjudge.net/problem/UVA-1331 题意:输入一个多边形,找一个最大三角形面积最小的三角剖分,输出最大三角形的面积. 思路: 最优三角剖分. dp[i][j]表示从 ...
- DP——最优三角形剖分
[动态规划]凸多边形最优三角剖分 枚举三角行,再递归三角形旁边的两个多边形.
- Voronoi图和Delaunay三角剖分
刷题的时候发现了这么一个新的东西:Voronoi图和Delaunay三角剖分 发现这个东西可以$O(nlogn)$解决平面图最小生成树问题感觉非常棒 然后就去学了.. 看的n+e的blog,感谢n+e ...
- 动态规划——区间dp
在利用动态规划解决的一些实际问题当中,一类是基于区间上进行的,总的来说,这种区间dp是属于线性dp的一种.但是我们为了更好的分类,这里仍将其单独拿出进行分析讨论. 让我们结合一个题目开始对区间dp的探 ...
随机推荐
- count()与sum()
介绍Mysql中的count()与sum()区别 CREATE TABLE `result` ( `name` varchar(20) default NULL, `subject` varchar( ...
- nyoj914Yougth的最大化(二分搜索 + 贪心)
Yougth的最大化 时间限制:1000 ms | 内存限制:65535 KB 难度:4 描述 Yougth现在有n个物品的重量和价值分别是Wi和Vi,你能帮他从中选出k个物品使得单位重量的价值最大吗 ...
- WebView支持特效,页面内跳转(转载!)
webView = (WebView) findViewById(R.id.lottery_webview); webView.getSettings().setJavaScriptEnabled(t ...
- jquery的事件绑定
暂时有 bind(),live(),delegate(),on() 这四个事件监听函数 对应的4个事件解除函数分别是: unbind(),die(),undelegate(),off() bind:向 ...
- DataContext 数据在F5刷新频繁,会出现数据读取错误
DataContext 数据在F5刷新频繁,会出现数据读取错误 DataContext是 Linq to sql数据模型的底层数据库对象所有LInq数据表对象都是由它派生的, 只要建立一个数据库操作, ...
- ios Objective-C的动态特性
这是一篇译文,原文在此,上一篇文章就是受这篇文章启发,这次干脆都翻译过来. 过去的几年中涌现了大量的Objective-C开发者.有些是从动态语言转过来的,比如Ruby或Python,有些是从强类型语 ...
- IOS动态修改按钮响应时间
在项目开发中我们可能会遇到这样子的情况,比如在我们登陆的时候需要把数据发送给服务器进行比对,通常我们的做法是当用户点击按钮后,使用一个加载效果的view遮挡住当前界面,直到服务器返回数据或者超时.如果 ...
- 0基础学习ios开发笔记第一天
Ios操作 界面操作 快捷键 command + c 复制 command+v 粘贴 command +a 全选 command +s 保存 command +z 撤销 command +x 剪切 ...
- devenv 命令用法
devenv是VisualStudio的可执行程序,一般安装在“C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE”下. 这 ...
- mysql query insert中文乱码
mysql新建的表的charset都是utf8的. 在phpmyadmin里直接敲sql,中文可以insert进去的,但是在php代码里mysql_query同样的sql语句就是不行,保存到表里是乱码 ...