Cake ZOJ - 3537(判断凸包模板+最优三角剖分+区间dp详解)

zoj3537(区间dp) 最有三角形划分,凸包不会也抄了别人的凸包代码一直wa不明觉厉,不过dp算是想对了; #include #include #include #include #include using namespace std; typedef long long lld; #define oo 0x3f3f3f3f #define mod 1000000007 #define maxn 300+5 int 阅读详情

Cake ZOJ - 3537

 You want to hold a party. Here's a polygon-shaped cake on the table. You'd like to cut the cake into several triangle-shaped parts for the invited comers. You have a knife to cut. The trace of each cut is a line segment, whose two endpoints are two vertices of the polygon. Within the polygon, any two cuts ought to be disjoint. Of course, the situation that only the endpoints of two segments intersect is allowed.

The cake's considered as a coordinate system. You have known the coordinates of vexteces. Each cut has a cost related to the coordinate of the vertex, whose formula is costi, j = |xi + xj| * |yi + yj| % p. You want to calculate the minimum cost.

NOTICE: input assures that NO three adjacent vertices on the polygon-shaped cake are in a line. And the cake is not always a convex.

Input

There're multiple cases. There's a blank line between two cases. The first line of each case contains two integers, N and p (3 ≤ N, p ≤ 300), indicating the number of vertices. Each line of the following N lines contains two integers, x and y (-10000 ≤ x, y ≤ 10000), indicating the coordinate of a vertex. You have known that no two vertices are in the same coordinate.

Output

If the cake is not convex polygon-shaped, output "I can't cut.". Otherwise, output the minimum cost.

Sample Input

3 3
0 0
1 1
0 2

Sample Output

0
题意:

给定n个点的坐标,先问这些点是否能组成一个凸包,如果是凸包,问用不相交的线来切这个凸包使得凸包只由三角形组成,根据 cost(i, j) = |xi + xj| * |yi + yj| % p 算切线的费用,问最少的切割费用。

分析:

首先当然是要先判断是否是凸包了

因为之前没有写过凸包的题目所以这里就写一下判断凸包的算法


Andrew算法:

首先把所有点按照x从小到大排序,(如果x相同,按照y从小到大排序),删除重复点后得到的序列
p1,p2,....p1,p2,.... 然后把p1,p2p1,p2放到凸包中,相当于入栈。从p3p3开始,当新点在凸包“前进方向的左侧时继续即新点在栈顶点的左侧时入栈,如果在右侧,就依次删除最近加入的点,即删除栈顶,直到新点在栈顶左侧(有点像单调栈的操作)

如下图所示,新点p18p18在向量p10p15p10p15的右边(当前前进方向),因此需要从栈中删除p10,p15p10,p15,让p8p8的下一个点为p18p18.重复这个过程,知道碰到最右边的pnpn,就求出了下凸包。

这里写图片描述
然后再反过来从pnpn开始再做一次,求出上凸包,合并起来就是完整的凸包了
这里写图片描述

struct Point{
    int x,y;
    Point(){}
    Point(int xx,int yy):x(xx),y(yy){}
    void read(){
        scanf("%d%d",&x,&y);
    }
    bool operator < (const Point &other)const{
        if(x == other.x)
            return y < other.y;
        return x < other.x;
    }
    Point operator - (const Point &other)const{
        return Point(x - other.x,y - other.y);
    }
};
Point p[400],ch[400];
int n;
double Cross(Point A,Point B){
    return A.x * B.y - A.y * B.x;
}
int ConvexHull(){
    sort(p,p+n);
    int cnt = 0;
    for(int i = 0; i < n; i++){
        while(cnt > 1 && Cross(ch[cnt-1] - ch[cnt-2],p[i] - ch[cnt-2]) <= 0) cnt--;
        ch[cnt++] = p[i];
    }
    int k = cnt;
    for(int i = n-2; i >= 0; i--){
        while(cnt > k && Cross(ch[cnt-1] - ch[cnt-2],p[i] - ch[cnt-2]) <= 0) cnt--;
        ch[cnt++] = p[i];
    }
    if(n > 1) cnt--;
    return cnt;
}

介绍完了凸包我们再来看看这道题怎么做呢?

需要用到最优三角剖分:


最优三角剖分:

对于一个n个顶点的凸多边形,有很多种方法可以对它进行三角剖分,即用n-3条互不相交的对角线把凸多边形分成n-2个三角形。为每个三角形规定一个权值函数w(i,j,k),求让所有三角形权和最大的方案。

定义dp[i][j]为子多边形i,i+1,….j-1,j(i < j)的最优值,则边i-j在最优解中一定对应一个三角形i-k-j,其中(i < k < j)那么同理,在i-k间也一定能找到一个最优值,k-j之间也可以找到一个最优值,一次类推

如图:
这里写图片描述
因此状态转移方程为

dp[i][j]=max(dp[i][j],dp[i][k]+dp[k][j]+w(i,j,k))dp[i][j]=max(dp[i][j],dp[i][k]+dp[k][j]+w(i,j,k))

时间复杂度O(n3)O(n3),问题的解为dp[0][n−1]dp[0][n−1]


那么对于这道题就很明确了

状态转移方程为:

dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j]+cost[i][k]+cost[k][j])dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j]+cost[i][k]+cost[k][j])

三重for循环枚举ijk,即可,区间dp

code:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int INF = 0x3f3f3f3f;
int m,f[400][400],dp[400][400];
struct Point{
    int x,y;
    Point(){}
    Point(int xx,int yy):x(xx),y(yy){}
    void read(){
        scanf("%d%d",&x,&y);
    }
    bool operator < (const Point &other)const{
        if(x == other.x)
            return y < other.y;
        return x < other.x;
    }
    Point operator - (const Point &other)const{
        return Point(x - other.x,y - other.y);
    }
};
Point p[400],ch[400];
int n;
double Cross(Point A,Point B){
    return A.x * B.y - A.y * B.x;
}
int ConvexHull(){
    sort(p,p+n);
    int cnt = 0;
    for(int i = 0; i < n; i++){
        while(cnt > 1 && Cross(ch[cnt-1] - ch[cnt-2],p[i] - ch[cnt-2]) <= 0) cnt--;
        ch[cnt++] = p[i];
    }
    int k = cnt;
    for(int i = n-2; i >= 0; i--){
        while(cnt > k && Cross(ch[cnt-1] - ch[cnt-2],p[i] - ch[cnt-2]) <= 0) cnt--;
        ch[cnt++] = p[i];
    }
    if(n > 1) cnt--;
    return cnt;
}
int calc(Point a,Point b){
    return (abs(a.x + b.x) * abs(a.y + b.y)) % m;
}
int main(){
    while(scanf("%d%d",&n,&m) != EOF){
        memset(p,0,sizeof(p));
        memset(ch,0,sizeof(ch));
        memset(f,0,sizeof(f));
        for(int i = 0; i < n; i++){
            p[i].read();
        }
        if(n == 3){
            puts("0");
            continue;
        }
        if(ConvexHull() < n){
            printf("I can't cut.\n");
        }
        else{
            for(int i = 0; i < n; i++){
                for(int j = i+2; j < n; j++){
                    f[i][j] = f[j][i] = calc(ch[i],ch[j]);
                }
            }
            for(int i = 0; i < n; i++){
                for(int j = 0; j < n; j++){
                    dp[i][j] = INF;
                }
                dp[i][(i+1)%n] = 0;
            }
            for(int i = n-3; i >= 0; i--){
                for(int j = i+2; j < n; j++){
                    for(int k = i+1; k < j; k++){
                        dp[i][j] = min(dp[i][j],dp[i][k]+dp[k][j]+f[i][k]+f[k][j]);
                    }
                }
            }
            printf("%d\n",dp[0][n-1]);
        }
    }
    return 0;
}
STM32F407单一定时器输出4路不同频率及占空比的PWM波 阅读详情

相关推荐

Vivado IP核:AXI Uartlite的使用经验分享

1. IP基本设置 在Vivado中,打开IP Catalog,搜索“uart”: 双击“AXI Uartlite”,进入IP配置界面: 这里可以配置IP的具体参数,设置时钟频率、波特率等,完成后,生成IP即可。 2. IP的时序特点 点击下面的链接可以下载该IP核的官方指导文档: https://china.xilinx.com/support/documentation/ip_docume...

weixin_43265132的博客 1万+

ZOJ - 3537 Cake (凸包+经典区间dp)

题目链接:点击这里 题目大意: 给定 nnn 个点的坐标,如果这 nnn 个点能构成凸包,再用不相交的线来切这个凸包使得凸包只由三角形组成,切割代价是 cost(i,j)=∣xi+xj∣∗∣yi+yj∣cost(i, j) = |xi + xj| * |yi + yj| % pcost(i,j)=∣xi+xj∣∗∣yi+yj∣ ,求最少的切割费用。 题目分析: 先用把点排个序跑个凸包,如果是凸包再跑一下三角形划分的区间 dpdpdp ,其转移方程为:dp[i][j]=min(dp[i][j],dp[i][k

羊驼的博客 300

基于CNN的表情识别(FER)pytorch实现

Report for FER Jian Tang Abstract 我们使用卷积神经网络(CNN)实现了baby的面部表情识别(FER)。 数据上,我们获取了开源FER数据集FER2013[1],besides我们使用爬虫获取了baby相关的人脸图片,进行了手工分类标注以形成一个全新的baby FER数据集。 模型上,我们首先复现了Luan[2]的工作,即参考Kuo[3]在CVPR 2018上的工作并实现一个轻量的CNN网络,在FER2013上进行训练并得到了XXXX%的平均分类准确率(avg a

qq_20241587的博客 3683

ZOJ 3537-Cake(凸包+最优三角刨分+区间DP)

Cake Time Limit: 1 Second      Memory Limit: 32768 KB You want to hold a party. Here's a polygon-shaped cake on the table. You'd like to cut the cake into several triangle-shaped parts for th

信仰.的博客 811

专有钉钉小程序(浙政钉)开发搭建流程总览

最近公司有一个项目要做浙政钉,让我来负责做。靠,我一脸懵,开发了两年多不知道浙政钉是啥,感觉我眼界还是低了。然后就去百度、同事问了一圈才知道就是个钉钉小程序嘛,然后发布到浙政钉上了。就搭建项目跑起来我都肥了很多事,中间走了很多坑。正好领导让我写《钉钉小程序前端开发流程》,这想着也写个博客吧。下面就是整个流程及我所遇到的坑!

m0_53910290的博客 6355

abaqus热力耦合模拟教程学习笔记

学习资源:BV1je4y1a7Ku软件:abaqus2016以m为单位制。

qq_41900477的博客 2万+

ZOJ 3537-Cake(凸包+最优三角刨分+区间DP)

#include <stdio.h> #include <iostream> #include <string> #include <string.h> #include <algorithm> #include <math.h> using namespace std; struct node { int x,y; bo...

weixin_44879687的博客 216

新手小白 必须精进的 “ FLASH分区管理Code and Data ” !!!最强文章解析!!!

FLASH“代码区”和“数据区”不是每个项目都必须显式管理,但只要你的产品功能越来越丰富,对可靠性和扩展性要求提高,就一定要学会科学划分和使用。这也是嵌入式工程师进阶路上的必修课!

qq_75157958的博客 933

ZOJ 3537 Cake(凸包+区间DP)

思路:先判断是不是凸包,如果是的话,进行区间DP, dp[i][j] = min{dp[i][k] + dp[k][j] + cost[i][k] + cost[k[[j]} 代码: #include #include #include #include #include using namespace std; const int MAXN= 305; const int N = 3

Remilia's 626

AI大模型开发——transformer模型超全完整版(0基础可懂)

为了更深入的了解transformer模型,我们首先从transformer的诞生聊起吧。transformer在2017年由Vaswani等人首次提出,它摒弃了之前流行的循环神经网络和卷积神经网络的架构,引入了自注意力机制( Self-Attention),显著提高了处理序列数据的能力和效率。transformer模型的这种设计使其在处理长距离依赖问题时, 相比于传统的循环神经网络和长短期记忆网络(LSTM)表现得更加出色,至此, 开启了NLP技术的新篇章。

m0_74922316的博客 2120

Open3D (C++) 使用点云创建数字高程模型DEM

Open3D (C++) 使用点云创建数字高程模型DEM

点云侠的博客 1391

zoj 3537 Cake 【凸包 + 区间dp】 【最优三角剖分】

Cake Time Limit: 1 Second      Memory Limit: 32768 KB You want to hold a party. Here's a polygon-shaped cake on the table. You'd like to cut the cake into several triangle-shaped parts for the

世界很大 1802

工业缺陷检测:基于深度学习的表面缺陷分类

工业缺陷检测:基于深度学习的表面缺陷分类 ,人工智能,计算机视觉,大模型,AI,在现代工业生产中,产品质量直接影响企业的竞争力和声誉,工业缺陷检测作为质量把控的重要环节,其技术的发展至关重要。传统的人工检测方式效率低、成本高且易受主观因素影响,难以满足大规模、高精度的生产需求。随着深度学习技术的蓬勃发展,基于深度学习的工业表面缺陷分类方法凭借强大的特征提取和模式识别能力,成为解决工业缺陷检测难题的有效途径。本文将深入探讨基于深度学习的工业表面缺陷分类技术,结合详细的代码示例和概念解析。

不踩坑,不知道坑有多深;不总结,踩过的坑白踩。 3万+

zoj 3537 Cake (凸包 最优三角剖分)

题目链接这道题目是一道最优三角剖分的题目,其实也是一种区间dp里的一种应用,思路也很简单。这道题目还需要先是不是凸包,这里其实主要想记录一下凸包模板==#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; const dou

ciel_s的博客 503

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

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 the cake into several triangle-shaped parts for the invited comers. You have a knife to cut. The t

那些年 1917

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

zoj3537 Cake 【凸包+最优三角形划分】

判断输入的点能不能组成凸包(即所有点都要是凸包的顶点) 然后就是求最优三角形划分问题,也就是区间dp 感觉这种区间dp还是记忆化搜索写起来比较方便 记忆化搜索#include<bits/stdc++.h> using namespace std; const int inf=0x3fffffff; int top,s[10024];struct data { int x,y; } p[100

禅境花园 1057

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

ZOJ-3537 Cake(区间dp+凸包最优三角形剖分)

A - Cake  ZOJ - 3537  题意:一块多边形,如果是凹多边形则直接输出“I can't cut.”,否则将他进行三角形剖分,每切一刀的花费是 |x1+x2|*|y1+y2|%p,x和y分别是点的坐标,问剖分的最小花费是多少 最优三角形剖分:对于一个n个顶点的凸多边形,可以用n-3条互不相交的对角线b把凸多边形分成n-2个三角形, 定义dp[i][j

十分残念的博客 630

ZOJ3537 解题报告及总结

题目意思就是 给你一个多边形,先判断是否是凸包,然后再划分成一个一个三角形,求最小代价,两点之间画一条线的最小代价为 abs(xi + xj) * abs(yi + yj) % p 才做的时候,想法是枚举划分的线,根据分治的思想,大的多边形拆成两个小多边形,然后记忆化,复杂度超高难写不说(因为要记录i节点的nxt节点编号,不停地变来变去),还不知道wa在哪。。 后来想了下,既然最后一定是一个一个的三

CQU_HYX的专栏 584

zoj3537(三角剖分->区间dp)

不说区间dp还真不造要往dp这边想。。 求完凸包每个多边形可以用2个端点表示,那么设d[i][j]为以ij为端点的凸多边形剖分完的最小代价 为了使转移看起来好看点这里就不把边ij算在内 d[i][j]=min{d[i][k]+d[k][j]+a[i][k]+a[k][j]}  k=i+1...j-1 这就变成了水dp了嘛。。 然后区间dp用记忆化搜索写起来十分舒服,比以前的写法要轻松

qkoqhh 315

ZOJ 3537

这道题,就是先判断是不是凸多边形。先求出凸包,如果所有点都在凸包上,那这些点就围成了凸多边形,反之则不是。然后就是分割凸多边形了,刚开始也想到了先确定一条边所在的三角形,从而确定分割的边。但边没选好,导致后续的状态很凌乱。后来看了相关的资料。先按一个顺序将多边形的n个点编号1--n。求f[1][n]先以边n--1为基准,确定其所在三角形,然后就得到了两个多边形。得到状态转移方程,f[1][n]=m

L&J COME!!!! 943

ZOJ-3537 Cake

凸包+区间DP第一次写区间DP的题,也是第一次写计算几何的题,找了一些模板用写完还是不太清楚区间DP具体是什么分类思路是借鉴这个人的:https://www.cnblogs.com/bhlsheji/p/4734765.html我写的是递归,他是递推#include&lt;iostream&gt; #include&lt;cstdio&gt; #include&lt;cstring&gt; #in...

wl16wzl的博客 314

ZOJ3537 Cake

ZOJ3537 Cake 传送门:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3537 题意: 给你几何形状的蛋糕,你需要按照顶点来切蛋糕,每次切蛋糕会产生一个贡献,\(val=cost_{i, j} *|x_i + x_j| * |y_i + y_j| % p\) 问你把蛋糕切成几个三角形所需要的最小花费 题解: 区间...

buerdepepeqi的优快云博客 266

ZOJ 3537 Cake 计算几何+区间dp

#include<bits/stdc++.h>using namespace std; typedef long long ll; const int inf = 0x3fffffff; struct node{ int x,y; }N[510],ans[510]; bool X(node a,node b,node c){ return (b.x-a.x)*(c.y-a.y)-(c

qq_33859479的博客 248

ZOJ 3537 简单凸包+DP

/* 简单学习了凸包,基本照着代码抄 凸包好像就是排序后跑一个polygon函数,就能得到一个凸包了 原理的话用平面直角坐标系的斜率理解凸包之后,图上的点被排序成顺时针排列的点 此时就是区间dp的思路了 */#include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include

beihai2013 522

Zoj 3537 区间DP

转自:http://blog.youkuaiyun.com/woshi250hua/article/details/7824433 状态转移方程弄懂了,但是因为没有做计算几何,所以凸包的求解看不懂。。。。以后看。。。。先刷DP AC代码如下: #include #include #include #include using namespace std; #define MAX 0x3f3f3

马德里小铁匠的铁匠铺 757
上一篇: Yet Another Problem On a Subsequence(dp+组合数)
下一篇: Least common multiple (数论+完全背包)
Guuuuuu老师儿
博客等级 码龄9年 259粉丝 718原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值