ZOJ 3537 Cake 求凸包 区间DP
题意:给出一些点表示多边形顶点的位置(如果多边形是凹多边形就不能切),切多边形时每次只能在顶点和顶点间切,每切一次都有相应的代价。现在已经给出计算代价的公式,问把多边形切成最多个不相交三角形的最小代价是多少。
思路:首先判断多边形是否是凸多边形,之后就是区间dp了。
求出凸包后,按逆时针来看。
设置dp[i][j]为从顶点i到顶点j所围成凸多边形的最优解。
枚举切点k (i < k < j)
dp[i][j] = min(dp[i][k] + dp[k][j] + cost[i][k] + cost[k][j]);
- #include<bits/stdc++.h>
- using namespace std;
- const int MAXN = ;
- struct point {
- int x,y;
- friend bool operator < (const point &a,const point &b) {
- if (a.y == b.y) return a.x < b.x;
- return a.y < b.y;
- }
- }src[MAXN];
- int cost[MAXN][MAXN];
- int N,P;
- int dp[MAXN][MAXN];
- point save[MAXN],tmp[MAXN];
- int cross(point p0,point p1,point p2) {
- return (p1.x - p0.x) * (p2.y - p0.y) - (p1.y - p0.y) * (p2.x - p0.x);
- }
- int graphm(point * p,int n) {
- sort(p,p + n);
- save[] = p[];
- save[] = p[];
- int top = ;
- for(int i = ; i < n ; i++){
- while(top && cross(save[top],p[i],save[top-]) >= )top--;
- save[++top] = p[i];
- }
- int mid = top;
- for(int i = n - ; i >= ; i--){
- while(top > mid && cross(save[top],p[i],save[top-]) >= ) top--;
- save[++top]=p[i];
- }
- return top;
- }
- int getcost(point a,point b) {
- return (abs(a.x + b.x) * abs(a.y+b.y)) % P;
- }
- int main() {
- while (scanf("%d%d",&N,&P) != EOF) {
- for (int i = ; i < N ; i++) scanf("%d%d",&src[i].x,&src[i].y);
- int num = graphm(src,N);
- if (num < N) {
- printf("I can't cut.\n");
- }
- else {
- memset(cost,,sizeof(cost));
- for (int i = ; i < N ; i++) {
- for (int j = i + ; j < N ; j++) cost[i][j] = cost[j][i] = getcost(save[i],save[j]);
- }
- memset(dp,0x3f,sizeof(dp));
- for (int i = ; i < N ; i++) dp[i][(i + ) % N] = ;
- for (int d = ; d <= N ; d++) {
- for (int i = ; i + d - < N ; i++) {
- int j = d + i - ;
- 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)
题目链接: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-sha ...
- Cake(凸包+区间DP)
You want to hold a party. Here's a polygon-shaped cake on the table. You'd like to cut the cake into ...
- zoj 3537 Cake 区间DP (好题)
题意:切一个凸边行,如果不是凸包直接输出.然后输出最小代价的切割费用,把凸包都切割成三角形. 先判断是否是凸包,然后用三角形优化. dp[i][j]=min(dp[i][j],dp[i][k]+dp[ ...
- 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+最优三角剖分)
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)
这道题目是经典的凸包的最优三角剖分,不过这个题目给的可能不是凸包,所以要提前判定一下是否为凸包,如果是凸包的话才能继续剖分,dp[i][j]表示已经排好序的凸包上的点i->j上被分割成一个个小三 ...
- 区间DP Zoj 3537 Cake 区间DP 最优三角形剖分
下面是别人的解题报告的链接,讲解很详细,要注意细节的处理...以及为什么可以这样做 http://blog.csdn.net/woshi250hua/article/details/7824433 我 ...
- ZOJ 3537 Cake (区间DP,三角形剖分)
题意: 给出平面直角坐标系上的n个点的坐标,表示一个多边形蛋糕,先判断是否是凸多边形,若否,输出"I can't cut.".若是,则对这个蛋糕进行3角形剖分,切n-3次变成n-2 ...
随机推荐
- 第51天:封装可视区域大小函数client
一.client 可视区域 offsetWidth: width + padding + border (披着羊皮的狼) clientWidth: width + ...
- Urllib--爬虫
1.简单爬虫 from urllib import request def f(url): print('GET: %s' % url) resp = request.urlopen(url) #赋给 ...
- POJ.1797 Heavy Transportation (Dijkstra变形)
POJ.1797 Heavy Transportation (Dijkstra变形) 题意分析 给出n个点,m条边的城市网络,其中 x y d 代表由x到y(或由y到x)的公路所能承受的最大重量为d, ...
- UVA.357 Let Me Count The Ways (DP 完全背包)
UVA.357 Let Me Count The Ways (DP 完全背包) 题意分析 与UVA.UVA.674 Coin Change是一模一样的题.需要注意的是,此题的数据量较大,dp数组需要使 ...
- HDOJ.1051 Wooden Sticks (贪心)
Wooden Sticks 点我挑战题目 题意分析 给出T组数据,每组数据有n对数,分别代表每个木棍的长度l和重量w.第一个木棍加工需要1min的准备准备时间,对于刚刚经加工过的木棍,如果接下来的木棍 ...
- Spring多个数据源问题:DataSourceAutoConfiguration required a single bean, but * were found
原因: @EnableAutoConfiguration 这个注解会把配置文件号中的数据源全部都自动注入,不会默认注入一个,当使用其他数据源时再调用另外的数据源. 解决方法: 1.注释掉这个注解 2. ...
- LibreOJ #6220. sum(数论+构造)
题目大意:在数组中找出一些数,使它们的和能被n整除 这题标签是数学,那我就标题就写数论好了... 显然如果数组中有n的倍数直接取就行. 那假设数组中没有n的倍数,把数组中的数求前缀和后全部%n,会得到 ...
- stout代码分析之十:c++11之move和forward
stout中大量使用了c++11的特性,而c++11中move和forward大概是最神奇的特性了. 左值和右值的区别 ; // a是左值,0是右值 int b = rand(); // b是左值,r ...
- C语言双链表遍历,插入,删除
#include<stdio.h> #include<stdlib.h> #include <string.h> #define bzero(a, b) memse ...
- Tomcat设置开启时自动访问某个servlet类存在的问题
<servlet> <servlet-name>****</servlet-name> <servlet-class>****</servlet- ...