uva 1331 lrj-P279 三角剖分+区间dp

来源:互联网 发布:同步带轮计算软件 编辑:程序博客网 时间:2024/05/21 17:49

题意:

给出多边形,找出最大三角形面积最小的三角剖分

输出最大的三角形面积

题解:

仔细研究可以知道,第一个点和最后一个点组成的边,一定是在某一个三角形中

那么我们就通过这个边作为基准,任选一个点组合成三角形,进行划分,得到两个多边形,这个时候两个多边形的点一定是按照顺序走的

然后这两个多边形再继续上叙操作

这样的操作是为了保证点连续,方便计算

状态转移方程就可以很容易的写出来了

dp[i][j]=fmin(dp[i][j],fmax(area(i,j,k),fmax(dp[i][k],dp[k][j])));
进行这个计算的时候要保证i  j 是对角线,i=1&&j=n的时候例外,判断是否为对角线的判断方法见check函数


#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;struct node{    int x,y;}p[110];int n,T;double dp[55][55];double fabs(double t){return t<0.0?-t:t;}double fmin(double x1,double y1){return x1<y1?x1:y1;}double fmax(double  a,double  b){return a>b?a:b;}double area(int i,int j,int k){    return fabs((p[k].x-p[i].x)*(p[j].y-p[i].y)-           (p[j].x-p[i].x)*(p[k].y-p[i].y))*0.5;}bool check(int a,int b,int c){    for(int i=1;i<=n;i++){        if(i==a||i==b||i==c) continue;        double t=area(a,b,i)+area(a,c,i)+area(b,c,i)-area(a,b,c);        if(t<0) t=-t;        if(t<=0.0001) return 0;    }    return 1;}int main(){    //freopen("in.txt","r",stdin);    scanf("%d",&T);    while(T--)    {        scanf("%d",&n);        for(int i=1;i<=n;i++) scanf("%d%d",&p[i].x,&p[i].y);        for(int i=n;i>=1;i--){            for(int j=i+2;j<=n;j++){                dp[i][j]=0x3f3f3f3f;                for(int k=i+1;k<j;k++){                    if(check(i,j,k))                    dp[i][j]=fmin(dp[i][j],fmax(area(i,j,k),fmax(dp[i][k],dp[k][j])));                }            }        }        printf("%0.1lf\n",dp[1][n]);    }    return 0;}


阅读全文
0 0
原创粉丝点击