Cake ZOJ - 3537

题目链接

本题也是区间dp三角剖分板子题,只不过加入了判断是否是凸包,计算顺序要用凸包顺序(凸包板)

#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;
}
View Code

 

posted @ 2020-02-23 13:11  GRedComeT  阅读(123)  评论(0编辑  收藏  举报