#include <stdio.h>
#include <iostream>
#include <string>
#include <string.h>
#include <algorithm>
#include <math.h>
using namespace std;
struct node
{
int x,y;
bool operator<(const node &a)const{ //x从小到大 x相等 y从小到大
if(x==a.x)return y<a.y;
return x<a.x;
}
}p[400],a[400];
node operator-(node a,node b)
{
node tem={a.x-b.x,a.y-b.y};
return tem;
}
int n,m;
int d[400][400],f[400][400];
double Cross(node A,node B)
{
return A.x*B.y-A.y*B.x;
}
int ConvexHull() //求出满足凸包个数
{
sort(p,p+n);
int cnt=0;
for(int i=0;i<n;i++)
{
while(cnt>1&&Cross(a[cnt-1]-a[cnt-2],p[i]-a[cnt-2])<=0)cnt--;//两条边叉积要>0,从左到右
a[cnt++]=p[i];
}
int k=cnt;
for(int i=n-2;i>=0;i--) //从右到左
{
while(cnt>k&&Cross(a[cnt-1]-a[cnt-2],p[i]-a[cnt-2])<=0)cnt--;
a[cnt++]=p[i];
}
if(n>1)cnt--;
return cnt;
}
int dfs(int x,int y)
{
if(d[x][y]!=-1)return d[x][y];
if(y-x<=2)return 0;
d[x][y]=1e9;
int i;
for(i=x+1;i<y;i++)
d[x][y]=min(dfs(x,i)+dfs(i,y)+f[x][i]+f[i][y],d[x][y]);
//printf("%d %d %d %d %d\n",x,y,d[x][y],f[x][i],f[i][y]);
return d[x][y];
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(d,-1,sizeof(d));
for(int i=0;i<n;i++)
scanf("%d%d",&p[i].x,&p[i].y);
if(n==3)
{
puts("0");
continue;
}
if(ConvexHull()<n)puts("I can't cut.");
else
{
//for(int i=0;i<n;i++)printf("%d %d\n",a[i].x,a[i].y);
for(int i=0;i<n;i++)
for(int j=i+2;j<n;j++)
f[i][j]=f[j][i]=abs(a[i].x+a[j].x)*abs(a[i].y+a[j].y)%m;
printf("%d\n",dfs(0,n-1));
}
}
}
ZOJ 3537-Cake(凸包+最优三角刨分+区间DP)
最新推荐文章于 2021-09-11 20:52:38 发布