• ZOJ3537 Cake


    ZOJ3537 Cake

    传送门:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3537

    题意:

    给你几何形状的蛋糕,你需要按照顶点来切蛋糕,每次切蛋糕会产生一个贡献,(val=cost_{i, j} *|x_i + x_j| * |y_i + y_j| % p) 问你把蛋糕切成几个三角形所需要的最小花费

    题解:

    区间dp好题

    首先我们维护 一个凸包,如果这个几何形状只有三个点,那么就不需要切,花费为0

    然后维护出一个凸包出来,如果满足凸包的条件的话,我们就开始切三角形

    很显然我们需要维护一个花费最小的三角形剖分

    设置dp[i][j]为从顶点i到顶点j所围成凸多边形的最优解。

    枚举切点k (i < k < j)

    (dp[i][j] = min(dp[i][k] + dp[k][j] + cost[i][k] + cost[k][j]))

    代码:

    #include <set>
    #include <map>
    #include <cmath>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    typedef long long LL;
    typedef pair<int, int> pii;
    typedef unsigned long long uLL;
    #define ls rt<<1
    #define rs rt<<1|1
    #define lson l,mid,rt<<1
    #define rson mid+1,r,rt<<1|1
    #define bug printf("*********
    ")
    #define FIN freopen("input.txt","r",stdin);
    #define FON freopen("output.txt","w+",stdout);
    #define IO ios::sync_with_stdio(false),cin.tie(0)
    #define debug1(x) cout<<"["<<#x<<" "<<(x)<<"]
    "
    #define debug2(x,y) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<"]
    "
    #define debug3(x,y,z) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<" "<<#z<<" "<<z<<"]
    "
    const int maxn = 3e5 + 5;
    const int INF = 0x3f3f3f3f;
    const int mod = 1e9 + 7;
    LL quick_pow(LL x, LL y) {
        LL ans = 1;
        while(y) {
            if(y & 1) {
                ans = ans * x % mod;
            } x = x * x % mod;
            y >>= 1;
        } return ans;
    }
    struct Point {
        int x, y;
        Point() {}
        Point(int xx, int yy): x(xx), y(yy) {}
        void read() {
            scanf("%d%d", &x, &y);
        }
        bool operator < (const Point &other)const {
            if(x == other.x)
                return y < other.y;
            return x < other.x;
        }
        Point operator - (const Point &other)const {
            return Point(x - other.x, y - other.y);
        }
    };
    Point P[400], ch[400];
    int n, m;
    double Cross(Point A, Point 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(ch[cnt - 1] - ch[cnt - 2], P[i] - ch[cnt - 2]) <= 0) cnt--;
            ch[cnt++] = P[i];
        }
        int k = cnt;
        for(int i = n - 2; i >= 0; i--) {
            while(cnt > k && Cross(ch[cnt - 1] - ch[cnt - 2], P[i] - ch[cnt - 2]) <= 0) cnt--;
            ch[cnt++] = P[i];
        }
        if(n > 1) cnt--;
        return cnt;
    }
    int calc(Point a, Point b) {
        return (abs(a.x + b.x) * abs(a.y + b.y)) % m;
    }
    int f[505][505];
    int dp[505][505];
    int main() {
    #ifndef ONLINE_JUDGE
        FIN
    #endif
        while(~scanf("%d%d", &n, &m)) {
            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) {
                printf("I can't cut.
    ");
            } else {
                for(int i = 0; i < n; i++) {
                    for(int j = i + 2; j < n; j++) {
                        f[i][j] = f[j][i] = calc(ch[i], ch[j]);
                    }
                }
                for(int i = 0; i < n; i++) {
                    for(int j = 0; j < n; j++) {
                        dp[i][j] = INF;
                    }
                    dp[i][(i + 1) % n] = 0;
                }
                for(int i = n - 3; i >= 0; i--) {
                    for(int j = i + 2; j < n; j++) {
                        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]);
                        }
                    }
                }
                printf("%d
    ", dp[0][n - 1]);
            }
        }
        return 0;
    }
    
    每一个不曾刷题的日子 都是对生命的辜负 从弱小到强大,需要一段时间的沉淀,就是现在了 ~buerdepepeqi
  • 相关阅读:
    eclipse 直接向cloudfoundry部署应用
    jenkins slave节点服务 之 标签
    cloud foundry 中 url map/unmap
    公司Oracle生产库某用户中毒【AfterConnect.sql】
    怎样在 Linux 上查看某个端口的相关信息?
    怎样修改 VS Code 主题?
    怎样安装并编译TypeScript?
    怎样坚持写博客?
    第一个shell脚本
    python处理excel之读:xlrd模块
  • 原文地址:https://www.cnblogs.com/buerdepepeqi/p/11219887.html
Copyright © 2020-2023  润新知