uva1331 Minimax Triangulation

题目大意:

按照顺时针或者逆时针的顺序给出多边的点,要将这个多边形分解成n-2个三角形,要求使得这些三角行中面积最大的三角形面积尽量小,求最小值。

/*
    dp[i][j]表示从第i个点到第j个点,划分成j-i-1个三角形的最优解,然后每次转移时,枚举长度和左边界始点,那么根据长度和左边界点就可以知道右边界点,然后枚举左边界和右边界中间的点k,dp[i][j] = min(dp[i][j], max(max(dp[i][k], dp[k][j]), Area(i, k, j)).但是有一个问题,即i,k,j三点围成的三角形是否符合要求,判断的条件即为是否存在除i,k,j三点外的一点位于三角形中,有面积法判断。
*/
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>

using namespace std;
const int N = 100;
const double INF = 0x3f3f3f3f3f3f;
const double eps = 1e-9;

struct point {
    double x, y;
    void get() {
        scanf("%lf%lf", &x, &y);
    }
}p[N];

int n;
double dp[N][N];

double area (point a, point b, point c) {
    return fabs((b.x-a.x)*(c.y-a.y) - (c.x-a.x)*(b.y-a.y))/2;
}

bool judge(int a,int b,int c) {//是否存在除i,k,j三点外的一点位于三角形中 
    double cur=area(p[a],p[b],p[c]);
    for(int i=0;i<n;i++) {
        if(i==a||i==b||i==c)
            continue;
        double tmp=area(p[a],p[b],p[i])+area(p[b],p[c],p[i])+area(p[c],p[a],p[i]);
        if(fabs(tmp-cur)<eps)
            return false;
    }
    return true;
}

double solve () {
    for (int i = 0; i < 2; i++) {
        for (int j = 0; j < n; j++)
            dp[j][(j+i)%n] = 0;
    }

    for (int i = 0; i < n; i++)
        dp[i][(i+2)%n] = area(p[i], p[(i+1)%n], p[(i+2)%n]);
    for(int k=3;k<n;k++){
            for(int i=0;i<n;i++){
                int t=(i+k)%n;
                dp[i][t]=INF;
                for(int j=(i+1)%n;j!=t;j=(j+1)%n){
                    if(judge(i,t,j))dp[i][t]=min(dp[i][t],max(max(dp[i][j],dp[j][t]),area(p[i], p[j], p[t])));
                }
            }
        }

    double ans = INF;
    for (int i = 0; i < n; i++)
        ans = min (ans, dp[i][(i+n-1)%n]);
    return ans;
}

int main () {
    freopen("Cola.in","r",stdin);
    int cas;
    scanf("%d", &cas);
    while (cas--) {
        scanf("%d", &n);
        for (int i = 0; i < n; i++)
            p[i].get();

        printf("%.1lf
", solve());
    }
    return 0;
}
100分
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
int t,n;
const double INF = 0x3f3f3f3f3f3f;
const double eps = 1e-9;
double s[60][60][60],dp[60][60];
struct node{
    double x,y;
}pos[60];
double count(int i,int j,int k){//计算面积 
    double x1=pos[i].x,x2=pos[j].x,x3=pos[k].x;
    double y1=pos[i].y,y2=pos[j].y,y3=pos[k].y;
    double xx1=x1-x3,xx2=x2-x3;
    double yy1=y1-y3,yy2=y2-y3;
    double res=fabs((xx1*yy2-xx2*yy1)/2.0);
    return res;
}
bool judge(int a,int b,int c){
    double cur=s[a][b][c];
    for(int i=1;i<=n;i++){
        if(i==a||i==b||i==c)continue;
        double tmp=s[a][b][i]+s[a][c][i]+s[b][c][i];
        if(fabs(tmp-cur)<=eps)return 0;
    }
    return 1;
}
int main(){
    freopen("Cola.in","r",stdin);
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        memset(s,0,sizeof(s));
        memset(dp,0,sizeof(dp));
        for(int i=0;i<n;i++)scanf("%lf%lf",&pos[i].x,&pos[i].y);
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                for(int k=0;k<n;k++){
                    //s[i][j][k]=INF;
                    if(i!=j&&i!=k&&j!=k)
                        s[i][j][k]=count(i,j,k);
                }
                    
        for(int i=0;i<n;i++)dp[i][(i+2)%n]=s[i][(i+1)%n][(i+2)%n];
        for(int k=3;k<n;k++){
            for(int i=0;i<n;i++){
                int t=(i+k)%n;
                dp[i][t]=INF;
                for(int j=(i+1)%n;j!=t;j=(j+1)%n){
                    if(judge(i,t,j))dp[i][t]=min(dp[i][t],max(max(dp[i][j],dp[j][t]),s[i][j][t]));
                }
            }
        }
        double ans=INF;
        for(int i=0;i<n;i++)
        ans=min(ans,dp[i][(i+n-1)%n]);
        printf("%.1lf
",ans);
    }
} 
wa 预处理了所有三角形的面积就迷之wa了
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<ctime>
using namespace std;
int t,n;
int main(){
    srand(time(0));
    t=rand()%6+2;
    printf("%d
",t);
    while(t--){
        n=rand()%3+3;
        printf("%d
",n);
        for(int i=1;i<=n;i++){
            int x=rand()%20+1,y=rand()%20+1;
            printf("%d %d
",x,y);
        }
    }
}
data 造小数据
#include<iostream>
#include<cstdio>
#include<cstring>
#include<windows.h>
using namespace std;
int main(){
    int t=1000000;
    while(t--){
        system("1331_data>Cola.in");
        system("1331_thmyl<Cola.in>1.out");
        system("1331_std<Cola.in>2.out");
        if(system("fc 1.out 2.out"))break;
    }
    system("pause");
}
对拍
原文地址:https://www.cnblogs.com/thmyl/p/7411908.html