ZOJ 3537 Cake 求凸包 区间DP

题意:给出一些点表示多边形顶点的位置(如果多边形是凹多边形就不能切),切多边形时每次只能在顶点和顶点间切,每切一次都有相应的代价。现在已经给出计算代价的公式,问把多边形切成最多个不相交三角形的最小代价是多少。

思路:首先判断多边形是否是凸多边形,之后就是区间dp了。

求出凸包后,按逆时针来看。

设置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<bits/stdc++.h>
using namespace std;
const int MAXN = 310;
struct point {
    int x,y;
    friend bool operator < (const point &a,const point &b) {
        if (a.y == b.y) return a.x < b.x;
        return a.y < b.y;
    }
}src[MAXN];
int cost[MAXN][MAXN];
int N,P;
int dp[MAXN][MAXN];

point save[MAXN],tmp[MAXN];
int cross(point p0,point p1,point p2) {
    return (p1.x - p0.x) * (p2.y - p0.y) - (p1.y - p0.y) * (p2.x - p0.x);
}

int graphm(point * p,int n) {
    sort(p,p + n);
    save[0] = p[0];
    save[1] = p[1];
    int top = 1;
    for(int i = 0 ; i < n ; i++){
        while(top && cross(save[top],p[i],save[top-1]) >= 0)top--;
        save[++top] = p[i];
    }

    int mid = top;
    for(int i = n - 2 ; i >= 0 ; i--){
        while(top > mid && cross(save[top],p[i],save[top-1]) >= 0) top--;
        save[++top]=p[i];
    }
    return top;
}

int getcost(point a,point b) {
    return (abs(a.x + b.x) * abs(a.y+b.y)) % P;
}

int main() {
    while (scanf("%d%d",&N,&P) != EOF) {
        for (int i = 0 ; i < N ; i++) scanf("%d%d",&src[i].x,&src[i].y);
        int num = graphm(src,N);
        if (num < N) {
            printf("I can‘t cut.\n");
        }
        else {
            memset(cost,0,sizeof(cost));
            for (int i = 0 ; i < N ; i++) {
                for (int j = i + 2 ; j < N ; j++) cost[i][j] = cost[j][i] = getcost(save[i],save[j]);
            }
            memset(dp,0x3f,sizeof(dp));
            for (int i = 0 ; i < N ; i++) dp[i][(i + 1) % N] = 0;
            for (int d = 2 ; d <= N ; d++) {
                for (int i = 0 ; i + d - 1 < N ; i++) {
                    int j = d + i - 1;
                    for (int k = i + 1; k < j ; k++)
                        dp[i][j] = min(dp[i][j],dp[i][k] + dp[k][j] + cost[i][k] + cost[k][j]);
                }
            }
            printf("%d\n",dp[0][N - 1]);
        }
    }
    return 0;
}
时间: 2024-10-13 22:30:35

ZOJ 3537 Cake 求凸包 区间DP的相关文章

ZOJ 3537 Cake(凸包+区间DP)

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3537 题目大意:给出一些点表示多边形顶点的位置,如果不是凸多边形(凸包)则不能切,直接输出"I can't cut."切多边形时每次只能在顶点和顶点间切,每切一次的花费为 cost(i, j) = |xi + xj| * |yi + yj| % p.问把多边形切成最多个不相交三角形的最小代价是多少. 解题思路:先求出凸包,接着可以用区间DP解决,设dp

zoj 3537 Cake (凸包判定+区间dp)

Cake Time Limit: 1 Second      Memory Limit: 32768 KB You want to hold a party. Here's a polygon-shaped cake on the table. You'd like to cut the cake into several triangle-shaped parts for the invited comers. You have a knife to cut. The trace of eac

zoj 3537 Cake (凸包确定+间隔dp)

Cake Time Limit: 1 Second      Memory Limit: 32768 KB You want to hold a party. Here's a polygon-shaped cake on the table. You'd like to cut the cake into several triangle-shaped parts for the invited comers. You have a knife to cut. The trace of eac

Cake(凸包+区间DP)

You want to hold a party. Here's a polygon-shaped cake on the table. You'd like to cut the cake into several triangle-shaped parts for the invited comers. You have a knife to cut. The trace of each cut is a line segment, whose two endpoints are two v

ZOJ 3469 Food Delivery(区间DP)

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4255 题意:n个人订餐.n个人位于一条线上,饭店也在这条线上.每个人有一个脾气值p.若第i分钟得到他预定的饭不满意度为p*i.送饭人的速度已知.求一种送饭顺序使得总不满意度最小. 思路:设f[i][j][0],f[i] [j][1]分别表示将[i,j]区间的送完,最后停在左边或右边的最小不满意度.那么我们在DPf[i][j][0]时可以从f[i+1][j]进行转 移

ZOJ - 3537 Cake (凸包+区间DP+最优三角剖分)

Description You want to hold a party. Here's a polygon-shaped cake on the table. You'd like to cut the cake into several triangle-shaped parts for the invited comers. You have a knife to cut. The trace of each cut is a line segment, whose two endpoin

ZOJ 3537 Cake (区间DP,三角形剖分)

题意: 给出平面直角坐标系上的n个点的坐标,表示一个多边形蛋糕,先判断是否是凸多边形,若否,输出"I can't cut.".若是,则对这个蛋糕进行3角形剖分,切n-3次变成n-2份三角形蛋糕给小伙伴吃,但是每切一次需要一个费用,公式是:cost[i][j] = |xi + xj| * |yi + yj| % p 表示在两点i和j之间切一刀的费用.问最少费用是多少? 思路: 判断是否凸多边形需要用到求凸包的Andrew算法,时间复杂度为O(nlogn),然后判断凸包内的点数是否为n就行

zoj 3537 Cake(区间dp)

这道题目是经典的凸包的最优三角剖分,不过这个题目给的可能不是凸包,所以要提前判定一下是否为凸包,如果是凸包的话才能继续剖分,dp[i][j]表示已经排好序的凸包上的点i->j上被分割成一个个小三角形的最小费用,那么dp[i][j] = min(dp[i][k]+dp[k][j]+cost[i][k]+cost[k][j]),其中,(j >= i+ 3,i+1<=k<=j-1,cost[i][k]为连一条i到k的线的费用). 上一个图,来自博客http://blog.csdn.net

ZOJ - 3537 —— Cake

题目:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=23543 1. 因为没有三个点在同一直线上,即每个点都是多边形的一个顶点而不会有点在某条边上,所以要判断这个多边形是不是凸多边性,可以用像凸包问题那样做,得到的凸包的关节点以及它们的个数num,若num==n (全体点的个数),那么是凸多边形:否则,不是凸多边形. 2. 如果判断是凸多边形后,就要开始正式的DP了. 我们都知道,这种成环的数组的DP,可以将环拆开,变成区