zoj 3537 Cake 区间DP (好题)
题意:切一个凸边行,如果不是凸包直接输出。然后输出最小代价的切割费用,把凸包都切割成三角形。
先判断是否是凸包,然后用三角形优化。
dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j]+w[i][k]+w[j][k]);
w[i][j]代表i到j点的切割费用。
dp[i][j]:表示以i到j点的最小费用。则可把凸边行分成三个部分的费用。两个凸边行(i,k),(k,j)和两条边的费用(i,k),(j,k),k为枚举的三角形顶点。
Zoj 3537 Cake (DP_最优三角形剖分)
//#pragma comment(linker, "/STACK:167772160")//手动扩栈~~~~hdu 用c++交
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<queue>
#include<stack>
#include<cmath>
#include<set>
#include<algorithm>
#include<vector>
// #include<malloc.h>
using namespace std;
#define clc(a,b) memset(a,b,sizeof(a))
#define LL long long
const int inf = 0x3f3f3f3f;
const double eps = 1e-;
const double pi = acos(-);
// inline int r(){
// int x=0,f=1;char ch=getchar();
// while(ch>'9'||ch<'0'){if(ch=='-') f=-1;ch=getchar();}
// while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
// return x*f;
// }
const int maxn=;
struct Point{
int x, y;
Point(int x=, int y=):x(x),y(y) { }
}p[maxn]; // typedef Point Vector; int w[maxn][maxn],dp[maxn][maxn],n,m; // Vector operator + (const Vector& A, const Vector& B)
// {
// return Vector(A.x+B.x, A.y+B.y);
// }
// Vector operator - (const Point& A, const Point& B)
// {
// return Vector(A.x-B.x, A.y-B.y);
// }
// double Cross(const Vector& A, const Vector& B)
// {
// return A.x*B.y - A.y*B.x;
// } // Vector Rotate(const Vector& A, double rad)
// {
// return Vector(A.x*cos(rad)-A.y*sin(rad), A.x*sin(rad)+A.y*cos(rad));
// } // bool operator < (const Point& p1, const Point& p2)
// {
// return p1.x < p2.x || (p1.x == p2.x && p1.y < p2.y);
// } // bool operator == (const Point& p1, const Point& p2)
// {
// return p1.x == p2.x && p1.y == p2.y;
// }
// // 点集凸包
// // 如果不希望在凸包的边上有输入点,把两个 <= 改成 <
// // 如果不介意点集被修改,可以改成传递引用
// vector<Point> ConvexHull(vector<Point> p)
// {
// // 预处理,删除重复点
// sort(p.begin(), p.end());
// p.erase(unique(p.begin(), p.end()), p.end()); // int n = p.size();
// int m = 0;
// vector<Point> ch(n+1);
// for(int i = 0; i < n; i++)
// {
// while(m > 1 && Cross(ch[m-1]-ch[m-2], p[i]-ch[m-2]) <= 0) m--;
// ch[m++] = p[i];
// }
// int k = m;
// for(int i = n-2; i >= 0; i--)
// {
// while(m > k && Cross(ch[m-1]-ch[m-2], p[i]-ch[m-2]) <= 0) m--;
// ch[m++] = p[i];
// }
// if(n > 1) m--;
// ch.resize(m);
// return ch;
// }
Point save[],temp[];
int xmult(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;
}
int Graham(Point *p,int n) {
int i;
sort(p,p + n,cmp);
save[] = p[];
save[] = p[];
int top = ;
for(i = ;i < n; i++){ while(top && xmult(save[top],p[i],save[top-]) >= )top--;
save[++top] = p[i];
}
int mid = top;
for(i = n - ; i >= ; i--){ while(top>mid&&xmult(save[top],p[i],save[top-])>=)top--;
save[++top]=p[i];
}
return top;
} int main(){
// freopen("in.txt","r",stdin);
while(~scanf("%d%d",&n,&m)){
for(int i=;i<n;i++) scanf("%d%d",&p[i].x,&p[i].y);
clc(dp,);
clc(w,);
int v;
v=Graham(p,n);
// printf("%d\n",(int)v.size());
if(v<n) printf("I can't cut.\n");
else{
for (int i = ; i < n; ++i)
for (int j = i + ; j < n; ++j)
w[i][j] = w[j][i] =(abs(save[i].x + save[j].x) * abs(save[i].y+save[j].y)) % m;
for (int i = ; i < n; ++i) {
for (int j = ; j < n; ++j)
dp[i][j] = inf;
dp[i][(i+)%n] = ;
}
for (int i = n - ; i >= ; --i)
for (int j = i + ; j < n; ++j)
for (int k = i + ; k <= j - ; ++k)
dp[i][j] = min(dp[i][j],dp[i][k]+dp[k][j]+w[i][k]+w[k][j]);
printf("%d\n",dp[][n-]);
}
}
return ;
}
zoj 3537 Cake 区间DP (好题)的更多相关文章
- zoj 3537 Cake(区间dp)
这道题目是经典的凸包的最优三角剖分,不过这个题目给的可能不是凸包,所以要提前判定一下是否为凸包,如果是凸包的话才能继续剖分,dp[i][j]表示已经排好序的凸包上的点i->j上被分割成一个个小三 ...
- 区间DP Zoj 3537 Cake 区间DP 最优三角形剖分
下面是别人的解题报告的链接,讲解很详细,要注意细节的处理...以及为什么可以这样做 http://blog.csdn.net/woshi250hua/article/details/7824433 我 ...
- 又一道区间DP的题 -- P3146 [USACO16OPEN]248
https://www.luogu.org/problemnew/show/P3146 一道区间dp的题,以区间长度为阶段; 但由于要处理相邻的问题,就变得有点麻烦; 最开始想了一个我知道有漏洞的方程 ...
- poj 2955 Brackets (区间dp基础题)
We give the following inductive definition of a “regular brackets” sequence: the empty sequence is a ...
- ZOJ 3537 Cake(凸包+区间DP)
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3537 题目大意:给出一些点表示多边形顶点的位置,如果不是凸多边形 ...
- 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
题意:给出一些点表示多边形顶点的位置(如果多边形是凹多边形就不能切),切多边形时每次只能在顶点和顶点间切,每切一次都有相应的代价.现在已经给出计算代价的公式,问把多边形切成最多个不相交三角形的最小代价 ...
- zoj 3537 Cake (凸包确定+间隔dp)
Cake Time Limit: 1 Second Memory Limit: 32768 KB You want to hold a party. Here's a polygon-sha ...
- 状态压缩---区间dp第一题
标签: ACM 题目 Gappu has a very busy weekend ahead of him. Because, next weekend is Halloween, and he is ...
随机推荐
- CSRF攻击原理解析与对策研究
1.引言 跨站点请求伪造(Cross—Site Request Forgery).以下简称CSRF.是一种广泛存在的网站漏洞.Gmail.YouTube等著名网站都有过CSRF漏洞.甚至包 ...
- POJ3697+BFS+hash存边
/* 疾速优化+hash存边 题意:给定一个包含N(1 ≤ N ≤ 10,000)个顶点的无向完全图,图中的顶点从1到N依次标号.从这个图中去掉M(0 ≤ M ≤ 1,000,000)条边,求最后与顶 ...
- VS2013与MySql建立连接;您的项目引用了最新实体框架;但是,找不到数据链接所需的与版本兼容的实体框架数据库 EF6使用Mysql的技巧
因为之前都是看别人的项目,而没有自己从头到尾建立一个项目,所以这次尝试搭建时就出现了问题,主要是ASP.Net MVC项目中VS2013和MySql的连接. 第一个问题: 数据库表已建好,相应的数据库 ...
- codeforces #310 div1 D
一开始写了个暴力模拟绳子的摆动轨迹 然后在Test 16 T掉了 后来%了一下别人的代码,发现需要对特殊情况进行特殊处理 首先我们考虑绳子的向右摆动,设当前位置为p,绳子当前长度为L 如果其旋转中心位 ...
- PHP基础语法3
文件系统 判断文件是否存在 如果只是判断文件存在,使用file_exists就行,file_exists不仅可以判断文件是否存在,同时也可以判断目录是否存在,从函数名可以看出, is_file是确切的 ...
- 【转】wireshark过滤规则
WireShark过滤语法 1.过滤IP,如来源IP或者目标IP等于某个IP 例子:ip.src eq 192.168.1.107 or ip.dst eq 192.168.1.107或者ip.add ...
- border-radius的水平和竖直半径
通常我们设置border-radius都只区分四个角的, 如border-radius: 1em 2em. 其实每个角的border-radius都由两部分组成, 水平半径和竖直半径. 要设置水平和竖 ...
- node.js EventEmitter发送和接收事件
EventEmitter是nodejs核心的一部分.很多nodejs对象继承自EventEmitter,用来处理事件,及回调.api文档地址: http://nodejs.org/api/events ...
- Linux下修改PATH的方法
Linux下修改PATH的方法 1.直接在命令行里敲 PATH=$PATH:/path1:/path2:/pathN用户登出之后PATH恢复原样. 只是临时起作用. 2.修改~目录下bash_prof ...
- Java开发之多线程下载和断点续传
代码实现了多线程下载和断点续传功能 import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream ...