ZOJ 3537 Cake (凸包 + 区间DP && 最优三角形剖分)
题目链接:Here
题意:
给定 \(n\) 个点的坐标,先问这些点能否组成一个凸包,如是凸包,问用不相交的线来切这个凸包使得凸包只由三角形组成,根据 \(cost_{i, j} = |x_i + x_j| * |y_i + y_j| \% p\)算切线的费用,问最少的切割费用。
解题思路:参考于 ZeroClock,感谢!
经典的最优三角剖分模型加一点计算几何的知识。
先判断是否为凸包,这个排个序就好弄,搬了一下凸包函数排序的板子。
返回凸包中的顶点数量再与 \(n\) 比较。
这一步处理完之后就是用 \(n-3\) 条直线将凸包切成 \(n-2\) 个三角形。

我们要切的是以 \(1\) 和 \(n\) 为起始点的凸包,由于切线不能相交,那么选择 \(1\) 点和 \(n\) 点必有另外一点 \(S\) 要和它们组成一个三角形,然后凸包被分成三个部分: \(k_0,k_1,k_2\) ,然后把 \(k_1\) 看成一个以 \(n\) 点 \(S\) 点位起始点的凸包,是不是又可以用相同的方法处理这个凸包呢?答案是肯定,就是这样慢慢地将凸包分成一个个子凸包计算费用,最后再更新到点 \(1\) 和点 \(n\) 为起始点的凸包。
模拟上面的过程,设 \(Dp[i][j]\) 为以 \(i\) 为起点,\(j\) 为终点的凸包被切割成一个个小三角形所需要的费用。
那么
\]
为连一条 \(i\) 到 \(k\) 的线的费用),因为 \(dp[i][j]\) 只表示为以 \(i\) 为起点,\(j\) 为终点的凸包内部被切割的费用,所以在连线的时候可以加上边界费用而不算重复计算。
const int N = 1e3 + 10, inf = 1e9;
struct Point {
int x, y;
} p[N];
int cost[N][N], n, m;
int f[N][N];
int abs(int x) {return x < 0 ? -x : x;}
int xmul(Point p1, Point p2, Point p0) {
return (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y);
}
bool cmp(const Point &a, const Point &b) {
if (a.y == b.y)return a.x < b.x;
return a.y < b.y;
}
Point save[400], temp[400];
int Graham(Point *p, int n) {
sort(p, p + n, cmp);
save[0] = p[0];
save[1] = p[1];
int top = 1;
for (int i = 0; i < n; ++i) {
while (top && xmul(save[top], p[i], save[top - 1]) >= 0) top --;
save[++top] = p[i];
}
int mid = top;
for (int i = n - 2; i >= 0; --i) {
while (top > mid && xmul(save[top], p[i], save[top - 1]) >= 0) top --;
save[++top] = p[i];
}
return top;
}
int Count(Point a, Point b) {
return (abs(a.x + b.x) * abs(a.y + b.y)) % m;
}
int main() {
cin.tie(nullptr)->sync_with_stdio(false);
while (cin >> n >> m) {
for (int i = 0; i < n; ++i) cin >> p[i].x >> p[i].y;
int tot = Graham(p, n); // 求凸包
if (tot < n) {cout << "I can't cut.\n"; continue;}
memset(cost, 0, sizeof(cost));
// for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j)cost[i][j] = 0;
for (int i = 0; i < n; ++i)
for (int j = i + 2; j < n; ++j) cost[j][i] = cost[i][j] = Count(save[i], save[j]);
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) f[i][j] = inf;
f[i][(i + 1) % n] = 0;
}
for (int i = n - 3; i >= 0; --i) // 注意三个for循环顺序
for (int j = i + 2; j < n; ++j) //因为要保证在算dp[i][j]时dp[i][k]和dp[k][j]时已经计算,所以i为逆序,j要升序
for (int k = i + 1; k <= j - 1; ++k)
f[i][j] = min(f[i][j], f[i][k] + f[k][j] + cost[i][k] + cost[k][j]);
cout << f[0][n - 1] << "\n";
}
}
ZOJ 3537 Cake (凸包 + 区间DP && 最优三角形剖分)的更多相关文章
- 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 ...
- ZOJ 3537 Cake (区间DP,三角形剖分)
题意: 给出平面直角坐标系上的n个点的坐标,表示一个多边形蛋糕,先判断是否是凸多边形,若否,输出"I can't cut.".若是,则对这个蛋糕进行3角形剖分,切n-3次变成n-2 ...
- ZOJ 3537 (凸包 + 区间DP)(UNFINISHED)
#include "Head.cpp" const int N = 10007; int n, m; struct Point{ int x,y; bool operator &l ...
- ZOJ 3537 Cake(凸包判定+区间DP)
Cake Time Limit: 1 Second Memory Limit: 32768 KB You want to hold a party. Here's a polygon-shaped c ...
- 区间DP Zoj 3537 Cake 区间DP 最优三角形剖分
下面是别人的解题报告的链接,讲解很详细,要注意细节的处理...以及为什么可以这样做 http://blog.csdn.net/woshi250hua/article/details/7824433 我 ...
- zoj 3537 Cake 区间DP (好题)
题意:切一个凸边行,如果不是凸包直接输出.然后输出最小代价的切割费用,把凸包都切割成三角形. 先判断是否是凸包,然后用三角形优化. dp[i][j]=min(dp[i][j],dp[i][k]+dp[ ...
- ZOJ 3537 Cake(凸包+区间DP)
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3537 题目大意:给出一些点表示多边形顶点的位置,如果不是凸多边形 ...
- ZOJ 3537 Cake 求凸包 区间DP
题意:给出一些点表示多边形顶点的位置(如果多边形是凹多边形就不能切),切多边形时每次只能在顶点和顶点间切,每切一次都有相应的代价.现在已经给出计算代价的公式,问把多边形切成最多个不相交三角形的最小代价 ...
- zoj 3537 Cake (凸包确定+间隔dp)
Cake Time Limit: 1 Second Memory Limit: 32768 KB You want to hold a party. Here's a polygon-sha ...
- ZOJ 3537 Cake
区间DP. 首先求凸包判断是否为凸多边形. 如果是凸多边形:假设现在要切割连续的一段点,最外面两个一定是要切一刀的,内部怎么切达到最优解就是求子区间最优解,因此可以区间DP. #include< ...
随机推荐
- UData+StarRocks在京东物流的实践
1 背景 数据服务与数据分析场景是数据团队在数据应用上两个大的方向,行业内大家有可能会遇到下面的问题: 1.1 数据服务 烟囱式开发模式:每来一个需求开发一个数据服务,数据服务无法复用,难以平台化,技 ...
- 全面的.NET微信网页开发之JS-SDK使用步骤、配置信息和接口请求签名生成详解
JSSDK使用步骤 步骤一:绑定安全域名: 先登录微信公众平台进入"公众号设置"的"功能设置"里填写"JS接口安全域名". 步骤二:引入JS ...
- 解决Spring Boot Mail无法发送HTML格式的邮件
Spring Boot版本:2.6.2 查阅spring-boot-starter-mail源码的MimeMessageHelper.setText方法,发现有个Boolean类型参数控制是否是HTM ...
- 重写Nacos服务发现逻辑动态修改远程服务IP地址
背景 还是先说下做这个的背景,开发环境上了K8S,所有的微服务都注册在K8S内的Nacos,注册地址为K8S内部虚拟IP,K8S内的服务之间相互调用没有问题,但是本机开发联调调用其他微服务就访问不到. ...
- [USACO2007OPENS] Fliptile S
题目描述 FJ 知道,智商高的奶牛产奶量也大,所以他为奶牛们准备了一个翻动瓦片的益智游戏. 在一个 \(M \times N\) 的方阵上(\(1 \leq M,N \leq 15\)),每个格子都有 ...
- Blazor入门100天 : 自做一个支持长按事件的按钮组件
好长时间没继续写这个系列博客了, 不知道大家还记得我吗? 话不多说,直接开撸. 1. 新建 net8 blazor 工程 b19LongPressButton 至于用什么模式大家各取所需, 我创建的是 ...
- MySQL运维15-一主一从读写分离
一.读写分离介绍 读写分离,是把数据库的读和写分开操作,以应对不同的数据库服务器.主数据库提供写操作,从数据库提供读操作,这样能有效的减轻单台数据库的压力. 二.一主一从原理 MySQL的主从复制是基 ...
- ElasticSearch之Create index API
创建指定名称的index. 命令样例如下: curl -X PUT "https://localhost:9200/testindex_002?pretty" -H 'Conten ...
- 秒懂ajax轮询、long poll 、websocket
ajax轮询 场景再现: 客户端:啦啦啦,有没有新信息(Request) 服务端:没有(Response) 客户端:啦啦啦,有没有新信息(Request) 服务端:没有..(Response) 客户端 ...
- 用Roslyn玩转代码之一: 解析与执行字符串表达式
最近框架中的可视化界面设计需要使用到表达式引擎(解析代码字符串并动态执行),之前旧框架的实现是将表达式字符串解析为语法树后解释执行该表达式,本文介绍如何使用Roslyn解析表达式字符串,并直接转换 ...