区间DP。

首先求凸包判断是否为凸多边形。

如果是凸多边形:假设现在要切割连续的一段点,最外面两个一定是要切一刀的,内部怎么切达到最优解就是求子区间最优解,因此可以区间DP。

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std; const int MAXN = ;
const int INF = 0x7FFFFFFF;
struct point
{
int x, y;
};
point List[MAXN];
point a[MAXN];
int dp[MAXN][MAXN];
int Stack[MAXN], top;
int n, p;
int tot; 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);
}
double dis(point p1, point p2)
{
return sqrt((double)(p2.x - p1.x)*(p2.x - p1.x) + (p2.y - p1.y)*(p2.y - p1.y));
}
bool cmp(point p1, point p2)
{
int tmp = cross(List[], p1, p2);
if (tmp>) return true;
else if (tmp == && dis(List[], p1)<dis(List[], p2)) return true;
else return false;
}
void init()
{
int i, k;
point p0;
scanf("%d%d", &List[].x, &List[].y);
p0.x = List[].x;
p0.y = List[].y;
k = ;
for (i = ; i<n; i++)
{
scanf("%d%d", &List[i].x, &List[i].y);
if ((p0.y>List[i].y) || ((p0.y == List[i].y) && (p0.x>List[i].x)))
{
p0.x = List[i].x;
p0.y = List[i].y;
k = i;
}
}
List[k] = List[];
List[] = p0; sort(List + , List + n, cmp);
} void graham()
{
int i;
if (n == ) { top = ; Stack[] = ; }
if (n == )
{
top = ;
Stack[] = ;
Stack[] = ;
}
if (n>)
{
for (i = ; i <= ; i++) Stack[i] = i;
top = ; for (i = ; i<n; i++)
{
while (top> && cross(List[Stack[top - ]], List[Stack[top]], List[i]) <= ) top--;
top++;
Stack[top] = i;
}
}
} int cost(int i, int j)
{
return (abs(a[i].x + a[j].x)*abs(a[i].y + a[j].y)) % p;
} void work()
{
int tmp = top + ; tot = ;
if (tmp != n) printf("I can't cut.\n");
else
{
while (top != -) a[tot++] = List[Stack[top--]];
for (int r = , i = tot; r<tot - ; r++, i++) a[i] = a[i - tot]; tot = * tot - ; for (int i = ; i < tot; i++)
for (int j = ; j < tot; j++)
dp[i][j] = INF; for (int i = ; i < tot; i++)
{
int st = i, en = st + - ;
dp[st][en] = ;
} for (int i = ; i<tmp; i++)
{
for (int j = ; j<tot; j++)
{
int st = j, en = st + i - ;
if (en >= tot) continue;
for (int k = st + ; k <= en - ; k++)
dp[st][en] = min(dp[st][en], dp[st][k] + dp[k][en] + cost(st, en));
}
} int ans = INF;
for (int i = ; i<tot; i++)
{
int st = i, en = st + tmp - - ;
if (en>=tot) continue;
ans = min(ans, dp[st][en]);
}
printf("%d\n", ans);
}
} int main()
{
while (~scanf("%d%d", &n, &p))
{
init();
graham();
work();
}
return ;
}

ZOJ 3537 Cake的更多相关文章

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

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

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

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

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

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

  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+最优三角剖分)

    Description You want to hold a party. Here's a polygon-shaped cake on the table. You'd like to cut t ...

  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

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

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

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

随机推荐

  1. One-Way Reform

    One-Way Reform time limit per test 2 seconds memory limit per test 256 megabytes input standard inpu ...

  2. JPA 系列教程7-双向多对多

    双向多对多的ddl语句 同单向多对多表的ddl语句一致 Student package com.jege.jpa.many2many; import java.util.HashSet; import ...

  3. Jquery 控制元素 上 下 移动

    <html> <head> <meta http-equiv="Content-Type" content="text/html; char ...

  4. php des 加密类

    <?php/** *@see Yii CSecurityManager; */class Des{ public static function encrypt($data,$key){ $mo ...

  5. Android中自定义veiw使用Java中的回调方法

    //------------------MainActivity----中---------------------------------- import android.os.Bundle;imp ...

  6. angular.js之路由的选择

    在一个单页面中,我们可以添加多个模块,使得网页只在需要的时候加载这个模块.模块的切换大致上可以代替网页的切换,于是,我们便可以通过模块的切换实现网页的切换,这个切换是按需加载的. 乍一看非常普通的东西 ...

  7. Android----->多线程的实现Thread、IntentService的运用

    首先建立一个Intent.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout x ...

  8. 十二月总结-and-2016年终总结

    回顾 今天是2016的最后一天了,所以今天来做一个年终总结是最好不过的了.各种期末考试随着而来,也就意味着在工大的第一个学期马上结束了.回顾一下这一年所获得或者失去的一些东西: 2月份在家焦虑的等待着 ...

  9. 【啊哈!算法】算法7:Dijkstra最短路算法

    上周我们介绍了神奇的只有五行的Floyd最短路算法,它可以方便的求得任意两点的最短路径,这称为“多源最短路”.本周来来介绍指定一个点(源点)到其余各个顶点的最短路径,也叫做“单源最短路径”.例如求下图 ...

  10. kick_ball

    package com.hereyouare.KickBall; import android.app.Activity; import android.app.AlertDialog; import ...