Cake ZOJ - 3537
本题也是区间dp三角剖分板子题,只不过加入了判断是否是凸包,计算顺序要用凸包顺序(凸包板)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; #define lowbit(x) ((x)&(-x)) typedef long long LL; typedef pair<int,int> pii; const double eps = 1e-7; const int INF = 0x3f3f3f3f; int dp[303][303]; int f[303][303]; int dcmp(double x) { if(fabs(x) < eps) return 0; return x < 0?-1:1; } struct Point { double x, y; Point friend operator - (Point a, Point b) { return {a.x-b.x, a.y-b.y}; } } points[303], s[303]; double crossProduct(Point a, Point b) { return a.x*b.y - a.y*b.x; } double dis(Point a, Point b) { Point c = a-b; return sqrt(c.x*c.x+c.y*c.y); } bool isConvexHull(int n) { sort(points+1, points+1+n, [&](Point& a, Point& b) { return a.y < b.y || (a.y == b.y && a.x < b.x); }); sort(points+2, points+1+n, [&](Point& a, Point& b) { double x = crossProduct(a-points[1], b-points[1]); if(dcmp(x) > 0 || (dcmp(x) == 0 && dcmp(dis(a, points[1])-dis(a, points[1]))<0)) return true; return false; }); s[1] = points[1], s[2] = points[2]; int t = 2; for(int i = 3; i <= n; ++i) { while(t >= 2 && dcmp(crossProduct(s[t] - s[t-1], points[i] - s[t-1])) <= 0) t--; s[++t] = points[i]; } return t == n; } int cost(Point a, Point b, int p) { return (abs(int(a.x+b.x)) * abs(int(a.y+b.y))) % p; } void run_case() { int n, p; while(cin >> n >> p) { for(int i = 1; i <= n; ++i) cin >> points[i].x >> points[i].y; bool flag = isConvexHull(n); if(!flag) { cout << "I can't cut.\n"; } else { for(int i = 1; i <= n; i++){ for(int j = i+2; j <= n; j++){ f[i][j] = f[j][i] = cost(s[i],s[j], p); } } for(int i = n-3; i >= 1; --i) { for(int j = i+2; j <= n; ++j) { dp[i][j] = INF; for(int k = i+1; k < j; ++k) dp[i][j] = min(dp[i][j], dp[i][k]+dp[k][j]+f[i][k]+f[k][j]); } } cout << dp[1][n] << "\n"; } } } int main() { ios::sync_with_stdio(false), cin.tie(0); cout.flags(ios::fixed);cout.precision(10); //int t; cin >> t; //while(t--) run_case(); cout.flush(); return 0; }