Uva 12660 - Ears Cutting
计算几何+dp。要求的是将一个多边形分解成三角形最小的切割长度。先预处理出两点是否可以连线(连线在多边形内),然后再dp。dp[ l ][ r ]表示第l个点到第r个点都切割成三角形需要的最小值。于是就可以写出转移方程。
dp[ l ][ r ] = min(d[ i ][ l ] + d[ i ][ r ] + dp[ l ][ i ] + dp[ i ][ r ] )。枚举第三点i,和l, r 构成三角形。。。然后更新dp[ l ][ r ]就行了。。。因为0, n - 1这两个点是相连的。所以最后答案就是dp[0][n - 1].
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
#define CLR(a, b) memset(a, b, sizeof(a))using namespace std;
const double eps = 1e-6;
const double INF = 1e18;int dcmp(double x) {if(fabs(x) < eps) return 0; else return x < 0 ? -1 : 1;
}
struct Point {double x, y;Point(double x=0, double y=0):x(x),y(y) { }void read(){scanf("%lf%lf", &x, &y);}
};typedef Point Vector;Vector operator + (Vector A, Vector B) { return Vector(A.x+B.x, A.y+B.y); }
Vector operator - (Point A, Point B) { return Vector(A.x-B.x, A.y-B.y); }
Vector operator * (Vector A, double p) { return Vector(A.x*p, A.y*p); }
Vector operator / (Vector A, double p) { return Vector(A.x/p, A.y/p); }bool operator < (const Point& a, const Point& b) {return a.x < b.x || (a.x == b.x && a.y < b.y);
}bool operator == (const Point& a, const Point &b) {return dcmp(a.x-b.x) == 0 && dcmp(a.y-b.y) == 0;
}double Dot(Vector A, Vector B) { return A.x*B.x + A.y*B.y; }
double Length(Vector A) { return sqrt(Dot(A, A)); }
double Angle(Vector A, Vector B) { return acos(Dot(A, B) / Length(A) / Length(B)); }
double angle(Vector v) { return atan2(v.y, v.x); }
double Cross(Vector A, Vector B) { return A.x*B.y - A.y*B.x; }//点在p线段上
bool OnSegment(Point p, Point a1, Point a2) {return dcmp(Cross(a1-p, a2-p)) == 0 && dcmp(Dot(a1-p, a2-p)) < 0; //线段包含短点时改成<=
}//线段相交判定
bool SegmentItersection(Point a1, Point a2, Point b1, Point b2)
{double c1 = Cross(a2-a1, b1-a1), c2 = Cross(a2-a1, b2-a1),c3 = Cross(b2-b1, a1-b1), c4 = Cross(b2-b1, a2-b1);return dcmp(c1)*dcmp(c2) < 0 && dcmp(c3)*dcmp(c4) < 0;
}const int N = 110;Point p[N];
int n;
bool c[N][N], vis[N][N];
double dp[N][N], d[N][N];int isPointInPolygon(Point a)
{int wn = 0;for (int i = 0; i < n; i++){if (OnSegment(a, p[i], p[(i + 1) % n])) return -1; //边界int k = dcmp(Cross(p[(i + 1) % n] - p[i], a - p[i]));int d1 = dcmp(p[i].y - a.y);int d2 = dcmp(p[(i + 1) % n].y - a.y);if (k > 0 && d1 <= 0 && d2 > 0) wn++;if (k < 0 && d2 <= 0 && d1 > 0) wn--;}if (wn != 0) return 1; //内部return 0; //外部
}bool ok(int a, int b)
{if(!isPointInPolygon((p[a] + p[b]) * 0.5)) return false;for(int i = 0; i < n; i ++){if(SegmentItersection(p[i], p[(i + 1) % n], p[a], p[b])) return false;if(i != a && i != b && OnSegment(p[i], p[a], p[b])) return false;}return true;
}void init()
{for(int i = 0; i < n; i ++){for(int j = 0; j < n; j ++){if(ok(i, j))c[i][j] = true;else c[i][j] = false;d[i][j] = Length(p[i] - p[j]);}}
}double dfs(int l, int r)
{if(vis[l][r]) return dp[l][r];if(r - l <= 2) return 0;vis[l][r] = true;double &ret = dp[l][r];ret = INF;for(int i = l + 2; i <= r - 2; i ++){if(c[l][i] && c[i][r])ret = min(ret, d[i][l] + d[i][r] + dfs(l, i) + dfs(i, r));}if(c[l][r - 1]) ret = min(ret, d[l][r - 1] + dfs(l, r - 1));if(c[l + 1][r]) ret = min(ret, d[l + 1][r] + dfs(l + 1, r));return ret;
}int main()
{int cas = 1;while(scanf("%d", &n) != EOF){for(int i = 0; i < n; i ++){p[i].read();}init();CLR(vis, 0);printf("Case %d: %.4lf\n", cas ++, dfs(0, n - 1));}
}
Uva 12660 - Ears Cutting相关推荐
- UVA - 10079 Pizza Cutting
/* 主要是画图,画很多图,找规律,找到规律以后,发现算是简单题思路的关键是:每次切割都与前(i-1)刀有交点的情况下,得到的块数是最大的 */ #include <iostream> t ...
- bnu 33970 Ears Cutting
和http://www.cnblogs.com/kuangbin/category/475693.html类似 最优三角剖分 #include<algorithm> #include< ...
- SJTU 《综合英语一》备考题
image 第一次作业 218.1.73.51_82_mod_quiz_review.php_attempt=1175851.png 第二次作业 218.1.73.51_82_mod_quiz_rev ...
- π-Algorithmist分类题目(1)
原题网站:Algorithmist,http://www.algorithmist.com/index.php/Main_Page π-Algorithmist分类题目(1) Sorting UVAL ...
- Cutting Sticks UVA - 10003
题解:dp[ i ][ j ]=min { dp[ i ][ k ]+dp[ k ][ j ] }+a[ j ]-a [i ]. 和石子归并是一样的问题,枚举区间的长度,然后更新这个区间的值. 1 # ...
- UVA - 10003 - Cutting Sticks
原命题链接:PDF/Vjudge 题目的意思是:告诉木棍的总长度,切点个数,和切点位置.每次切割花费的力气为切割的木棍的长度,求出最小花费的力气值. 还没怎么开始看dp,一开始看这道题目,想起了做过的 ...
- uva 10003——Cutting Sticks
题意:给定一长为L的木棍和n个切割点,每次切割的费用为切割的长度,求最小的费用. 思路:dp,子问题是区间(i,j)的最小费用,临界是(i,j)只有一个切割点.dp[i,j]=min(dp[i,k]+ ...
- UVA 10003 Cutting Sticks (区间dp)
题意: 给你一根木块,让你在n个点切块(不能改变顺序),使得总花费最小,看拿来切的那根木棍的长度. 代码: #include <map> #include <set> #inc ...
- UVA 10003 Cutting Sticks
大意:确定切割木棍的次序, 代价为当前木棍长度,使得切割的总的代价最小. 思路:我想了很久,后来发现状态转移方程可以这样表示:d[i][j] = min(d[i][j], d[i][k]+d[k][j ...
最新文章
- python装饰器教学_Python装饰器学习(九步入门)
- 如何像算法工程师一样,看待这个世界?
- 关于程序员就业岗位及岗位市场的思考
- python apscheduler 阻塞方式只用一个线程_框架APScheduler在python中调度使用的实例详解...
- GCD LCM UVA - 11388 (思维。。水题)
- vba判断文件是否存在的两种方法
- leetcode 1227 python
- Eclipse搭建SSH环境实现Struts2分页显示mysql数据库表中内容
- java.util 1.8_JDK1.8源码(四)——java.util.Arrays 类
- 知网HTML阅读是什么,HTML – 屏幕阅读器究竟是什么?我应该如何处理我的网站?...
- 从 Google 离职了!
- python 吉他_Python中用于比较吉他弦的Matplotlib幅值_频谱单位
- 从普通程序员到估值上亿的公司老板,他只用了1年!
- 微型计算机原理...,微型计算机原理
- java面试题之选择题
- 激光器发射光功率饱和值
- 浅谈XMLHttpRequest
- python神坑系列之深浅拷贝
- EventSource 引发的一系列事件
- 拍脑壳所想之 ——戏言面向对象
热门文章
- MCS-51单片机存储器结构-特殊功能寄存器 :堆栈指针SP(Stack Pointer)
- 剑指offter 动态规划
- 前端数组json遍历3种方式总结
- 360 全球关键信息基础设施网络安全分析报告
- C语言_因数、因子_质数(素数)、合数
- 牛客练习赛13 B 幸运数字Ⅱ 【暴力】【二分】
- 以想总结就来博客写写
- 德国语言+留学签证递交材料详解(上海)
- 大学计算机基础清华大学出版社 山东省高等学校教学改革项目,清华大学出版社-图书详情-《大学计算机基础(第2版)》...
- Ajax: A New Approach to Web Applications