题目链接: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)的更多相关文章

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

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

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

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

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

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

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

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

  6. ZOJ 3537 Cake 求凸包 区间DP

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

  7. zoj 3537 Cake (凸包确定+间隔dp)

    Cake Time Limit: 1 Second      Memory Limit: 32768 KB You want to hold a party. Here's a polygon-sha ...

  8. ZOJ 3537 Cake

    区间DP. 首先求凸包判断是否为凸多边形. 如果是凸多边形:假设现在要切割连续的一段点,最外面两个一定是要切一刀的,内部怎么切达到最优解就是求子区间最优解,因此可以区间DP. #include< ...

  9. [ZOJ]3541 Last Puzzle (区间DP)

    ZOJ 3541 题目大意:有n个按钮,第i个按钮在按下ti 时间后回自动弹起,每个开关的位置是di,问什么策略按开关可以使所有的开关同时处于按下状态 Description There is one ...

随机推荐

  1. JsonTools

    public class JsonTools { /// <summary> /// Generate Json string from the object /// </summa ...

  2. 在mvc中 怎么给@Html.HiddenFor()赋值

    @Html.HiddenFor(model => model.CreatedBy, new { @value=currentInfo.UserID}) value始终是null@Html.Tex ...

  3. codeforces div1 & div2 参与人员分数统计

    Analysis helps to see the nature of things.

  4. Nginx记录-Nginx配置

    1. 启动,停止和重新加载Nginx配置 要启动nginx,请运行可执行文件. 当nginx启动后,可以通过使用-s参数调用可执行文件来控制它. 使用以下语法: nginx -s signal 信号( ...

  5. 网页制作中最有用的免费Ajax和JavaScript代码库

    网上看到的一篇小文,挺有用的,收藏在这. 本文中,我整理了12个免费的Ajax和JavaScript代码库,可以帮助Web开发人员将应用程序提升到一个新水平. Ajax Instant Messeng ...

  6. 退役 AFO

    noi滚粗了 D类没学校要 回去高考 此博客停止更新 此文章可能会继续更新 看心情 [upd 2017.11.13] 看完今年noip log级别数据结构终于出现辣! 看来noip以后又多了一大块考点 ...

  7. Bzoj4763 雪辉

    Time Limit: 39 Sec  Memory Limit: 666 MBSubmit: 151  Solved: 80 Description 上次立下的NOIP退役Flag没有成功   这次 ...

  8. POJ 2485 Highways( 最小生成树)

    题目链接 Description The islandnation of Flatopia is perfectly flat. Unfortunately, Flatopia has no publ ...

  9. spring-boog-测试打桩-Mockito

    Mockito用于测试时进行打桩处理:通过它可以指定某个类的某个方法在什么情况下返回什么样的值. 例如:测试 controller时,依赖 service,这个时候就可以假设当调用 service 某 ...

  10. pywin32记录备忘

    项目地址:http://sourceforge.net/projects/pywin32/ 文档地址:http://docs.activestate.com/activepython/2.7/pywi ...