ZOJ 3537 Cake(凸包+区间DP)
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3537
题目大意:给出一些点表示多边形顶点的位置,如果不是凸多边形(凸包)则不能切,直接输出"I can't cut."
切多边形时每次只能在顶点和顶点间切,每切一次的花费为 cost(i, j) = |xi + xj| * |yi + yj| % p。
问把多边形切成最多个不相交三角形的最小代价是多少。
解题思路:先求出凸包,接着可以用区间DP解决,设dp[i][j]为以i为起点,j为终点的凸包被切成三角形的最小花费。
那么可以得到状态转移方程:dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j]+cost[i][k]+cost[k][j])。
不懂的可以看下图(非原创):
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<cmath>
#include<algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
const int N=;
const double eps = 1e-; int n,mod;
int dp[N][N],cost[N][N]; struct P
{
double x, y;
P(double x=, double y=):x(x), y(y) {}
double add(double a, double b){
if(fabs(a+b)<eps*(fabs(a)+fabs(b))) return ;
return a+b;
}
P operator + (P p){
return P(add(x, p.x), add(y, p.y));
}
P operator - (P p){
return P(add(x, -p.x), add(y, -p.y));
}
P operator *(double d){
return P(x*d, y*d);
}
double dot(P p){ //点积
return add(x*p.x, y*p.y);
}
double det(P p){ //差积
return add(x*p.y, -y*p.x);
}
}ps[N]; double dist(P a, P b){
return sqrt((b-a).dot(b-a));
} bool cmp_x(const P& p, const P& q){
if(p.x!=q.x) return p.x < q.x;
return p.y < q.y;
} vector<P> convex_hull(P *ps, int n){
sort(ps,ps+n,cmp_x);
int k = ; //凸包顶点数
vector<P> qs(n*);
//构造凸包的下侧
for(int i=; i<n; i++)
{
while(k> && (qs[k-]-qs[k-]).det(ps[i]-qs[k-])<=) k--;
qs[k++] = ps[i];
}
//构造凸包的上侧
for(int i=n-,t=k; i>=; i--)
{
while(k>t && (qs[k-]-qs[k-]).det(ps[i]-qs[k-])<=) k--;
qs[k++] = ps[i];
}
qs.resize(k-);
return qs;
} int getcost(P p1,P p2){
return abs((int)p1.x+(int)p2.x)*abs((int)p1.y+(int)p2.y)%mod;
} int main(){
while(~scanf("%d%d",&n,&mod)){
for(int i=;i<n;i++){
scanf("%lf%lf",&ps[i].x,&ps[i].y);
}
vector<P>tp;
tp=convex_hull(ps,n);
if(tp.size()<n){
puts("I can't cut.");
continue;
}
//注意,用获得的凸包做DP,即使用tp做DP,保证凸包上的点的顺序
memset(cost,,sizeof(cost));
memset(dp,,sizeof(dp));
for(int i=;i<n;i++){
for(int j=i+;j<n;j++){
cost[i][j]=getcost(tp[i],tp[j]);
}
}
for(int len=;len<n;len++){
for(int i=;i+len<n;i++){
int j=i+len;
dp[i][j]=INF;
for(int k=i+;k<=j-;k++){
dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j]+cost[i][k]+cost[k][j]);
}
}
}
printf("%d\n",dp[][n-]);
}
return ;
}
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 ...
- zoj 3537 Cake 区间DP (好题)
题意:切一个凸边行,如果不是凸包直接输出.然后输出最小代价的切割费用,把凸包都切割成三角形. 先判断是否是凸包,然后用三角形优化. dp[i][j]=min(dp[i][j],dp[i][k]+dp[ ...
- 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< ...
- [ZOJ]3541 Last Puzzle (区间DP)
ZOJ 3541 题目大意:有n个按钮,第i个按钮在按下ti 时间后回自动弹起,每个开关的位置是di,问什么策略按开关可以使所有的开关同时处于按下状态 Description There is one ...
随机推荐
- jq获取兄弟节点
$('#id').siblings() 当前元素所有的兄弟节点$('#id').prev() 当前元素前一个兄弟节点$('#id').prevaAll() 当前元素之前所有的兄弟节点$('#id'). ...
- 实用 zsh 插件
zsh 命令补全插件 zsh-users/zsh-autosuggestions laravel5(使用前提:安装了 oh-my-zsh) 使用方法,修改 ~/.zshrc,在 plugins 里面加 ...
- 题解【CF103D Time to Raid Cowavans】
Description 给一个序列 \(a\) ,\(m\) 次询问,每次询问给出 \(t, k\) .求 \(a_t + a_{t+k}+a_{t+2k}+\cdots+a_{t+pk}\) 其中 ...
- 「Vue」实用组件
一.时间格式 1.安装Moment模块 npm i moment -S2.main.js中设置全局过滤器 import moment from 'moment' Vue.filter('ctime', ...
- 《剑指offer》 面试题53 :正则表达式匹配 Java
引言:这道题情况比较复杂,边界条件较多,为了便于以后复习,整理一下.另外,由于C语言和Java对于字符串的操作存在不一样的地方,代码也存在改动. 题目:请实现一个函数用来匹配包含'.'和'*'的正则表 ...
- UIViewController的初始化
UIViewController的初始化一般有两个: -(instancetype)init; -(instancetype)initWithNibName:(NSString *)nibNameOr ...
- java字节码文件 helloworld
Java代码 \\A.java public class A{} 1 2 1 2 javac A.java \\得到 A.class javap -v A.class 下面是javap工具帮我们生成的 ...
- Mac下配置环境变量(转)
说明:Mac下一般使用bash作为默认shell 一.Mac系统的环境变量,加载顺序为: /etc/profile /etc/paths ~/.bash_profile ~/.bash_login ~ ...
- typora快捷键之速成笔记
使用心得:用起来相当的顺手,强烈推荐小伙伴使用该工具,内置快捷功能很贴心 工具下载: https://download.csdn.net/download/lele508994993/10392197 ...
- [整理]VS2010中如何添加“依赖","库目录","包含目录"
VS2010中如何添加“依赖","库目录","包含目录" 1. 添加编译所需要(依赖)的 lib 文件[解决方案资源管理器]“项目->属性-&g ...