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 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个点的坐标,先问这些点能否组成一个凸包,假设是凸包。问用不相交的线来切这个凸包使得凸包仅仅由三角形组成,依据costi, j = |xi + xj| * |yi + yj| % p算切线的费用,问最少的分割费用。


思路:
先判定凸包,求凸包后看点的个数有没有变化。

然后区间dp,dp[i][j]表示切凸多边形i~j时的最小花费,特殊情况顶点个数为2或者3时不用切了为0.
如图i~j引入两条切线ik和kj将凸多边形分为两个凸多边形和一个三角形。
转移dp[i][j]=min(dp[i][k]+dp[k][j]+cost[i][k]+cost[k][j]);
cost[i][j]为切i、j两点时的花费,当j=i+1时花费为0.(凸多边形为三角形)


代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#pragma comment (linker,"/STACK:102400000,102400000")
#define maxn 105
#define MAXN 100005
#define mod 1000000000
#define INF 0x3f3f3f3f
#define pi acos(-1.0)
#define eps 1e-8
typedef long long ll;
using namespace std; int cmp(int x)
{
if(fabs(x)<eps) return 0;
if(x>0) return 1;
return -1;
}
int sqr(int x)
{
return x*x;
}
struct point
{
int x,y;
point(){};
point(int a,int b):x(a),y(b){};
void input()
{
scanf("%d%d",&x,&y);
}
friend point operator +(const point &a,const point &b)
{
return point(a.x+b.x,a.y+b.y);
}
friend point operator -(const point &a,const point &b)
{
return point(a.x-b.x,a.y-b.y);
}
friend bool operator ==(const point &a,const point &b)
{
return cmp(a.x-b.x)==0&&cmp(a.y-b.y)==0;
}
friend point operator *(const point &a,const int &b)
{
return point(a.x*b,a.y*b);
}
friend point operator *(const int &a,const point &b)
{
return point(a*b.x,a*b.y);
}
friend point operator /(const point &a,const int &b)
{
return point(a.x/b,a.y/b);
}
int norm()
{
return sqrt(sqr(x)+sqr(y));
}
};
int det(const point &a,const point &b)
{
return a.x*b.y-a.y*b.x;
}
int dot(const point&a,const point &b)
{
return a.x*b.x+a.y*b.y;
}
int dist(const point &a,const point &b)
{
return (a-b).norm();
} struct polygon_convex
{
vector<point>p;
polygon_convex(int Size=0)
{
p.resize(Size);
}
};
bool comp_less(const point &a,const point &b)
{
return cmp(a.x-b.x)<0||cmp(a.x-b.x)==0&&cmp(a.y-b.y)<0;
}
polygon_convex convex_hull(vector<point> a)
{
polygon_convex res(2*a.size()+5);
sort(a.begin(),a.end(),comp_less);
a.erase(unique(a.begin(),a.end()),a.end());
int m=0;
for(int i=0;i<a.size();i++)
{
while(m>1&&cmp(det(res.p[m-1]-res.p[m-2],a[i]-res.p[m-2]))<=0) m--;
res.p[m++]=a[i];
}
int k=m;
for(int i=int(a.size())-2;i>=0;--i)
{
while(m>k&&cmp(det(res.p[m-1]-res.p[m-2],a[i]-res.p[m-2]))<=0) m--;
res.p[m++]=a[i];
}
res.p.resize(m);
if(a.size()>1) res.p.resize(m-1);
return res;
} int n,m,ans;
int dp[305][305],cost[305][305];
vector<point> pp; int main()
{
int i,j,t;
while(~scanf("%d%d",&n,&m))
{
vector<point> pp;
point tmp;
for(i=1;i<=n;i++)
{
scanf("%d%d",&tmp.x,&tmp.y);
pp.push_back(tmp);
}
polygon_convex tb=convex_hull(pp);
if(tb.p.size()!=n) printf("I can't cut.\n");
else
{
if(n==3)
{
printf("0\n");
continue ;
}
memset(cost,0,sizeof(cost));
for(i=0;i<n;i++)
{
for(j=i+2;j<n;j++)
{
cost[i][j]=(abs(tb.p[i].x+tb.p[j].x)*abs(tb.p[i].y+tb.p[j].y))%m;
}
}
memset(dp,0x3f,sizeof(dp));
for(i=0;i<n-2;i++)
{
dp[i][i+1]=0;
dp[i][i+2]=0;
}
dp[n-2][n-1]=0;
for(int len=4;len<=n;len++)
{
for(i=0;i<n;i++)
{
j=i+len-1;
if(j>=n) break ;
for(int k=i+1;k<=j-1;k++)
{
dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j]+cost[i][k]+cost[k][j]);
}
}
}
printf("%d\n",dp[0][n-1]);
}
}
return 0;
}
/*
3 3
0 0
1 1
0 2 4 10
0 0
2 0
0 2
2 2 5 11
1 1
1 3
3 1
4 2
3 4
*/




版权声明:本文博客原创文章,博客,未经同意,不得转载。

zoj 3537 Cake (凸包确定+间隔dp)的更多相关文章

  1. 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 ...

  2. 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 ...

  3. zoj 3537 Cake 区间DP (好题)

    题意:切一个凸边行,如果不是凸包直接输出.然后输出最小代价的切割费用,把凸包都切割成三角形. 先判断是否是凸包,然后用三角形优化. dp[i][j]=min(dp[i][j],dp[i][k]+dp[ ...

  4. ZOJ 3537 Cake(凸包+区间DP)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3537 题目大意:给出一些点表示多边形顶点的位置,如果不是凸多边形 ...

  5. ZOJ 3537 Cake 求凸包 区间DP

    题意:给出一些点表示多边形顶点的位置(如果多边形是凹多边形就不能切),切多边形时每次只能在顶点和顶点间切,每切一次都有相应的代价.现在已经给出计算代价的公式,问把多边形切成最多个不相交三角形的最小代价 ...

  6. zoj 3537 Cake(区间dp)

    这道题目是经典的凸包的最优三角剖分,不过这个题目给的可能不是凸包,所以要提前判定一下是否为凸包,如果是凸包的话才能继续剖分,dp[i][j]表示已经排好序的凸包上的点i->j上被分割成一个个小三 ...

  7. 区间DP Zoj 3537 Cake 区间DP 最优三角形剖分

    下面是别人的解题报告的链接,讲解很详细,要注意细节的处理...以及为什么可以这样做 http://blog.csdn.net/woshi250hua/article/details/7824433 我 ...

  8. ZOJ 3537 Cake (区间DP,三角形剖分)

    题意: 给出平面直角坐标系上的n个点的坐标,表示一个多边形蛋糕,先判断是否是凸多边形,若否,输出"I can't cut.".若是,则对这个蛋糕进行3角形剖分,切n-3次变成n-2 ...

  9. ZOJ 3537 (凸包 + 区间DP)(UNFINISHED)

    #include "Head.cpp" const int N = 10007; int n, m; struct Point{ int x,y; bool operator &l ...

随机推荐

  1. Perl中的单行凝视和多行凝视

    同其它大多数编程语言一样.Perl中的单行凝视也是#开头.比如: #print "Hello,World!"; 但多行凝视.不同的语言有不同的凝视方式,比方说: Java,C/C+ ...

  2. MVC模型与FishiGUI应用层MVC型号

    MVC概要: MVC (Modal View Controler)M是指数据模型,V是指用户界面,C则是控制器. 使用MVC的目的是将M和V的实现代码分离,从而使同一个程序能够使用不同的表现形式.比方 ...

  3. Android动画之二:View Animation

    作为一个博客<Android其中的动画:Drawable Animation>.android动画主要分为三大部分.上一篇博客已经解说Drawable Animation的使用方法,即逐帧 ...

  4. win7/win8通过媒体流(DLNA技术)共享音乐照片和视频

    http://www.jb51.net/os/windows/79421.html 工具/原料 Windows 7/8/10家庭高级版以上版本 家庭WiFi局域网(无须连接互联网) 支持DLNA的手机 ...

  5. Java应用中使用ShutdownHook友好地清理现场(转)

    在线上Java程序中经常遇到进程程挂掉,一些状态没有正确的保存下来,这时候就需要在JVM关掉的时候执行一些清理现场的代码.Java中得ShutdownHook提供了比较好的方案. JDK在1.3之后提 ...

  6. 怎么样cocos2d-x正在使用ECS(实体-包裹-制)建筑方法来开发一款游戏?

    简介 在我的博客,我翻译的几篇文章ECS文章.这些文章都是从Game Development站点.假设你对这个架构方式还不是非常了解的话.欢迎阅读理解 组件-实体-系统和实现 组件-实体-系统. 我发 ...

  7. 查看.a架构文件

    苹果公司现在要求所有新提交的评论app,我们必须支持64位架构.而我们的在线项目编制,操作员做了一堆SDK在需要访问,我们发现,在这个过程中,有些SDK的.a文件进入后,链接错误,如提示 Undefi ...

  8. [LeetCode66]Plus One

    题目: Given a non-negative number represented as an array of digits, plus one to the number. The digit ...

  9. 产品CEO?别傻了,你不是拿破仑

    编者按:本文出自技术产品经理Daniel Elizalde的博客,中文版由天地会珠海分舵进行编译. 全文针对如今流行的把产品经理比喻成"产品CEO"的这一说法进行深入的分析.跟大家 ...

  10. android得知----overridePendingTransition

    1 Activity动画是指从一个切换activity跳到另一个activity随着电影. 它由两部分组成:第一部分是一个activity动画出口:中的第二个另一部分activity动画被访问: 于A ...