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;
}
WSL2安装(详细过程) 适用于 Linux 的 windows 子系统允许开发人员直接在 Windows 上运行 GNU/Linux 环境 -- 包括大多数命令行工具、实用程序和应用程序,无需修改,而无需传统虚拟机或dualbot设置的开销。 阅读详情

相关推荐

CarPlay盒子选购避坑指南:为什么你的车机破解了却用不了?从USB设备ID说起

本文深入解析CarPlay盒子硬件兼容性问题,从USB设备ID匹配到车机适配逻辑,揭示破解成功却无法使用的根本原因。通过分析USB设备识别的核心要素和逆向工程usb_device_manager.xml文件,提供三种主流解决方案对比,并强调操作中的硬件保护机制,帮助车主避免常见陷阱。

weixin_30706691的博客 472

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

Ubuntu18.04环境搭建与疑难解析:从零复现YOLO-6D姿态估计算法

本文详细介绍了在Ubuntu18.04环境下从零开始复现YOLO-6D姿态估计算法的完整流程,包括系统配置、Conda环境搭建、PyTorch安装、依赖项管理、源代码获取、数据集准备以及训练验证过程。针对Singleshotpose算法的特殊需求,提供了详细的疑难解析和性能优化技巧,帮助开发者高效完成算法复现和应用部署。

weixin_30369041的博客 453

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

逆向实战:Soul聊天协议加密与Frida绕过检测

本文详细解析了Soul聊天协议逆向分析的全过程,重点介绍了如何利用Frida绕过应用的反调试检测机制。通过静态分析定位关键SO库,并编写Frida脚本动态Hook线程创建函数,成功实现对抗。文章还进一步追踪了基于DES算法的加密流程,并探讨了协议数据结构的解析方法,为移动应用安全研究提供了实战参考。

2w3e4r5t6y的博客 1131

python解析通达信dat与blk数据文件【附源码】

本文介绍了一个完整的通达信金融数据解析器项目,该项目攻克了通达信专有二进制文件格式解析的技术难题。项目采用模块化架构,从基础二进制解析到增强数据分类,最终实现智能语义化列名生成,形成完整的数据处理链路。核心技术包括自适应编码检测、智能数据类型推断和基于业务规则的语义化处理,解决了逆向工程、多编码兼容性等挑战。项目成果显著,解析成功率达100%,数据可读性大幅提升,开发效率提高50%,为量化交易、可视化分析等场景提供了可靠数据支持。该方案不仅具备技术创新性,更具有实际工程应用价值,为金融数据分析领域提供了可复

qq_36224726的博客 2688

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

晶圆测试(Wafer Sort)的核心技术与良率提升策略

晶圆测试(Wafer Sort)是芯片制造中的关键“入学考试”,通过探针台与自动测试设备(ATE)对晶圆上的芯片进行功能与参数测试,筛选不合格芯片以控制成本。本文深入解析了其核心技术,包括自动化视觉系统对准、测试流程优化策略,并探讨如何利用测试数据驱动良率提升,展望了DFT与AI智能测试的未来趋势。

e4f5g6h的博客 515

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

【IoT】 产品设计之结构设计:如何设计产品按键

1、硅胶按键功能实现有两种接触方式 1)硅胶按键按压在DOME片(锅仔片)上 通常用在手机、儿童手表手机、防水手机等防水设备上。 2)硅胶按键增加导电基,一种黑色的导电碳粒,实现回路导电 通常用在遥控器、电脑键盘、特殊设备上。 两种方式结构设计原理是一样的,按键的固定与配合间隙与行程要确保好。 2、硅胶遥控器按键的结构方式(导电基) 按键帽为大颗粒实心的,触点为黑色导电基,通过压注成型融合为一体,那么这种按键结构设计时需要注意那些呢? 最主要的是按键按压回弹的手感,由于没有DOME片实现

产品线负责人 8666

ARFoundation系列讲解-教程目录

一、教程目录 ARFoundation快速入门-01简介 ARFoundation快速入门-02环境搭建 ARFoundation快速入门-03环境配置之iOS ARFoundation快速入门-04环境配置之Android ARFoundation快速入门-05ARKit设备支持列表 ARFoundation快速入门-06ARCore设备支持列表 ARFoundation快速入门-07检查设备支持 ARFoundation快速入门-08平面检..........

a451319296的博客 3万+

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

Python 爬虫实战:就业市场趋势数据抓取与行业洞察

在当今竞争激烈的就业市场中,了解行业趋势和就业形势对于求职者、学生以及人力资源专业人士来说至关重要。通过获取和分析就业市场数据,我们可以深入了解不同行业的招聘需求、薪资水平、技能要求等关键信息,从而为职业规划和人才发展提供有力支持。

yansideyucsdn的博客 1406

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

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

ciel_s的博客 503

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

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

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

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

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

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、付费专栏及课程。

余额充值