题目链接: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\)​ 为终点的凸包被切割成一个个小三角形所需要的费用。

那么 ​

\[dp[i][j] = min(dp[i][k]+dp[k][j]+cost[i][k]+cost[k][j]),(j >= i+ 3,i+1<=k<=j-1,cost[i][k]
\]

为连一条 \(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 && 最优三角形剖分)的更多相关文章

  1. 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 ...

  2. ZOJ 3537 Cake (区间DP,三角形剖分)

    题意: 给出平面直角坐标系上的n个点的坐标,表示一个多边形蛋糕,先判断是否是凸多边形,若否,输出"I can't cut.".若是,则对这个蛋糕进行3角形剖分,切n-3次变成n-2 ...

  3. ZOJ 3537 (凸包 + 区间DP)(UNFINISHED)

    #include "Head.cpp" const int N = 10007; int n, m; struct Point{ int x,y; bool operator &l ...

  4. 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 ...

  5. 区间DP Zoj 3537 Cake 区间DP 最优三角形剖分

    下面是别人的解题报告的链接,讲解很详细,要注意细节的处理...以及为什么可以这样做 http://blog.csdn.net/woshi250hua/article/details/7824433 我 ...

  6. zoj 3537 Cake 区间DP (好题)

    题意:切一个凸边行,如果不是凸包直接输出.然后输出最小代价的切割费用,把凸包都切割成三角形. 先判断是否是凸包,然后用三角形优化. dp[i][j]=min(dp[i][j],dp[i][k]+dp[ ...

  7. ZOJ 3537 Cake(凸包+区间DP)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3537 题目大意:给出一些点表示多边形顶点的位置,如果不是凸多边形 ...

  8. ZOJ 3537 Cake 求凸包 区间DP

    题意:给出一些点表示多边形顶点的位置(如果多边形是凹多边形就不能切),切多边形时每次只能在顶点和顶点间切,每切一次都有相应的代价.现在已经给出计算代价的公式,问把多边形切成最多个不相交三角形的最小代价 ...

  9. zoj 3537 Cake (凸包确定+间隔dp)

    Cake Time Limit: 1 Second      Memory Limit: 32768 KB You want to hold a party. Here's a polygon-sha ...

  10. ZOJ 3537 Cake

    区间DP. 首先求凸包判断是否为凸多边形. 如果是凸多边形:假设现在要切割连续的一段点,最外面两个一定是要切一刀的,内部怎么切达到最优解就是求子区间最优解,因此可以区间DP. #include< ...

随机推荐

  1. 超实用:通过文字就可以操纵这款AI表格

    公众号「架构成长指南」,专注于生产实践.云原生.分布式系统.大数据技术分享. 工具介绍 今天给大家分享超实用的AI表格ChatExcel,这个工具是由北大团队在2022年3月开始开发的AI表格处理神器 ...

  2. C/S结构用户界面设计

    C/S结构用户界面设计 [实验编号] 10003809547j  图形用户界面设计 [实验学时] 8学时 [实验环境] l 所需硬件环境为微机: l 所需软件环境为Microsoft Visual S ...

  3. Access denied for user ‘root‘@‘localhost‘ (using password:YES)解决方法

    修改jdbc.properties文件的密码

  4. 【生活技巧记录】歌词Lyric生成及音乐标签嵌入

    前置工具准备: BesLyric:一款专门制作 网易云音乐 LRC 滚动歌词的软件! 搜索.下载.制作 歌词更方便! Foobar 2000:一款适用于 Windows 平台的高级免费软件音频播放器 ...

  5. Tensorflow2.0实战之GAN

    本文主要带领读者了解生成对抗神经网络(GAN),并使用提供的face数据集训练网络 GAN 入门 自 2014 年 Ian Goodfellow 的<生成对抗网络(Generative Adve ...

  6. 一款开源免费美观的WinForm UI控件库 - ReaLTaiizor

    前言 今天推荐一款基于MIT license开源.免费.美观的.NET WinForm UI控件库:ReaLTaiizor. 什么是WinForm? WinForm是一个传统的桌面应用程序框架,它基于 ...

  7. 有意思,我的GitHub账号值$23806.2,快来试试你的?

    睡不着,看到一个有意思的网站:Estimate Github Worth Generator. 它可以用来估算 GitHub 账号的价值.马上试了一下. 我的账号估值:$23806.2 操作很简单,点 ...

  8. DEDECMS 后台系统用户授权目录更改为无限级(默认为二级授权)

    在做一个学校的项目,分类有四级分类,总共一百多个分类,因为每个分类对应不同的老师,用于上传资料作为考核,但是添加系统用户的时候发现DEDECMS只有两级分类,所以修改啦一些代码,目前不知道是否修改完全 ...

  9. 字符集(Character Set)和编码(Encoding)的历史演化

    字符集(Character Set)和编码(Encoding)是两个相关但不同的概念,它们在计算机和信息技术领域用于处理文本数据. 字符集(Character Set): 字符集是一种定义了一组字符. ...

  10. Windows Server 2016配置NTP客户端

    前提:开通Windows Time 服务 输入services.msc进入服务管理界面,找到Windows Time 开启服务. 情况1:可以直接设置NTP时钟 控制面板--时钟和区域--设置时间和日 ...