计算几何+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相关推荐

  1. UVA - 10079 Pizza Cutting

    /* 主要是画图,画很多图,找规律,找到规律以后,发现算是简单题思路的关键是:每次切割都与前(i-1)刀有交点的情况下,得到的块数是最大的 */ #include <iostream> t ...

  2. bnu 33970 Ears Cutting

    和http://www.cnblogs.com/kuangbin/category/475693.html类似 最优三角剖分 #include<algorithm> #include< ...

  3. SJTU 《综合英语一》备考题

    image 第一次作业 218.1.73.51_82_mod_quiz_review.php_attempt=1175851.png 第二次作业 218.1.73.51_82_mod_quiz_rev ...

  4. π-Algorithmist分类题目(1)

    原题网站:Algorithmist,http://www.algorithmist.com/index.php/Main_Page π-Algorithmist分类题目(1) Sorting UVAL ...

  5. Cutting Sticks UVA - 10003

    题解:dp[ i ][ j ]=min { dp[ i ][ k ]+dp[ k ][ j ] }+a[ j ]-a [i ]. 和石子归并是一样的问题,枚举区间的长度,然后更新这个区间的值. 1 # ...

  6. UVA - 10003 - Cutting Sticks

    原命题链接:PDF/Vjudge 题目的意思是:告诉木棍的总长度,切点个数,和切点位置.每次切割花费的力气为切割的木棍的长度,求出最小花费的力气值. 还没怎么开始看dp,一开始看这道题目,想起了做过的 ...

  7. uva 10003——Cutting Sticks

    题意:给定一长为L的木棍和n个切割点,每次切割的费用为切割的长度,求最小的费用. 思路:dp,子问题是区间(i,j)的最小费用,临界是(i,j)只有一个切割点.dp[i,j]=min(dp[i,k]+ ...

  8. UVA 10003 Cutting Sticks (区间dp)

    题意: 给你一根木块,让你在n个点切块(不能改变顺序),使得总花费最小,看拿来切的那根木棍的长度. 代码: #include <map> #include <set> #inc ...

  9. UVA 10003 Cutting Sticks

    大意:确定切割木棍的次序, 代价为当前木棍长度,使得切割的总的代价最小. 思路:我想了很久,后来发现状态转移方程可以这样表示:d[i][j] = min(d[i][j], d[i][k]+d[k][j ...

最新文章

  1. python装饰器教学_Python装饰器学习(九步入门)
  2. 如何像算法工程师一样,看待这个世界?
  3. 关于程序员就业岗位及岗位市场的思考
  4. python apscheduler 阻塞方式只用一个线程_框架APScheduler在python中调度使用的实例详解...
  5. GCD LCM UVA - 11388 (思维。。水题)
  6. vba判断文件是否存在的两种方法
  7. leetcode 1227 python
  8. Eclipse搭建SSH环境实现Struts2分页显示mysql数据库表中内容
  9. java.util 1.8_JDK1.8源码(四)——java.util.Arrays 类
  10. 知网HTML阅读是什么,HTML – 屏幕阅读器究竟是什么?我应该如何处理我的网站?...
  11. 从 Google 离职了!
  12. python 吉他_Python中用于比较吉他弦的Matplotlib幅值_频谱单位
  13. 从普通程序员到估值上亿的公司老板,他只用了1年!
  14. 微型计算机原理...,微型计算机原理
  15. java面试题之选择题
  16. 激光器发射光功率饱和值
  17. 浅谈XMLHttpRequest
  18. python神坑系列之深浅拷贝
  19. EventSource 引发的一系列事件
  20. 拍脑壳所想之 ——戏言面向对象

热门文章

  1. MCS-51单片机存储器结构-特殊功能寄存器 :堆栈指针SP(Stack Pointer)
  2. 剑指offter 动态规划
  3. 前端数组json遍历3种方式总结
  4. 360 全球关键信息基础设施网络安全分析报告
  5. C语言_因数、因子_质数(素数)、合数
  6. 牛客练习赛13 B 幸运数字Ⅱ 【暴力】【二分】
  7. 以想总结就来博客写写
  8. 德国语言+留学签证递交材料详解(上海)
  9. 大学计算机基础清华大学出版社 山东省高等学校教学改革项目,清华大学出版社-图书详情-《大学计算机基础(第2版)》...
  10. Ajax: A New Approach to Web Applications