Interval DP.
First, the convex hull is judged whether it is a convex polygon.
If it is convex polygon: Suppose now to cut a continuous point, the outermost two must be cut a knife, the internal how to achieve the optimal solution is to find the sub-interval optimal solution, so can be interval DP.
#include <cstdio>#include<cmath>#include<cstring>#include<algorithm>#include<iostream>using namespacestd;Const intMAXN = +;Const intINF =0x7FFFFFFF;structpoint{intx, y;}; Point LIST[MAXN];p oint A[MAXN];intDP[MAXN][MAXN];intSTACK[MAXN], top;intn, p;inttot;intCross (Point p0, point P1, point p2) {return(p1.x-p0.x) * (P2.Y-P0.Y)-(P1.Y-P0.Y) * (p2.x-p0.x);}Doubledis (point p1, point p2) {returnsqrt ((Double) (p2.x-p1.x) * (p2.x-p1.x) + (P2.Y-P1.Y) * (P2.Y-p1.y));}BOOLCMP (Point P1, point p2) {intTMP = Cross (list[0], p1, p2); if(tmp>0)return true; Else if(TMP = =0&& Dis (list[0], p1) <dis (list[0], p2))return true; Else return false;}voidinit () {intI, K; Point P0; scanf ("%d%d", &list[0].x, &list[0].y); p0.x= list[0].x; P0.y= list[0].y; K=0; for(i =1; 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[0]; list[0] =P0; Sort (List+1, List +N, CMP);}voidGraham () {inti; if(n = =1) {top =0; stack[0] =0; } if(n = =2) {Top=1; stack[0] =0; stack[1] =1; } if(n>2) { for(i =0; I <=1; i++) Stack[i] =i; Top=1; for(i =2; i<n; i++) { while(top>0&& Cross (List[stack[top-1]], list[stack[top] [list[i]) <=0) top--; Top++; Stack[top]=i; } }}intCostintIintj) { return(ABS (a[i].x + a[j].x) *abs (a[i].y + a[j].y))%p;}voidWork () {intTMP = top +1; tot =0; if(tmp! = N) printf ("I can ' t cut.\n"); Else { while(Top! =-1) a[tot++] = list[stack[top--]]; for(intR =0, i = tot; R<tot-1; r++, i++) a[i] = a[i-tot]; Tot=2* Tot-1; for(inti =0; i < tot; i++) for(intj =0; J < tot; J + +) Dp[i][j]=INF; for(inti =0; i < tot; i++) { intst = i, en = st +2-1; Dp[st][en]=0; } for(inti =3; i<tmp; i++) { for(intj =0; j<tot; J + +) { intst = j, en = st + i-1; if(En >= tot)Continue; for(intK = st +1; K <= en-1; k++) Dp[st][en]= Min (Dp[st][en], dp[st][k] + Dp[k][en] +Cost (St, en)); } } intAns =INF; for(inti =0; i<tot; i++) { intst = i, en = st + tmp-1-1; if(En>=tot)Continue; Ans=min (ans, dp[st][en]); } printf ("%d\n", ans); }}intMain () { while(~SCANF ("%d%d", &n, &p)) {init (); Graham (); Work (); } return 0;}
ZOJ 3537 Cake