题意:
按顺序给定一些点,把这些点分割为n - 2个三角形,花费为最大三角形面积,求最小花费
分析:
区间dp,dp[i][j]表示完成区间[i,j]最小花费,dp[i][j]=min(dp[i][j],max(dp[i][k],dp[k][j],area(p[i],p[j],p[k]);(area表示三点确定面积),区间要循环考虑(首未相邻)。
#include <map> #include <set> #include <list> #include <cmath> #include <queue> #include <stack> #include <cstdio> #include <vector> #include <string> #include <cctype> #include <complex> #include <cassert> #include <utility> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> using namespace std; typedef pair<int,int> PII; typedef long long ll; #define lson l,m,rt<<1 #define pi acos(-1.0) #define rson m+1,r,rt<<11 #define All 1,N,1 #define read freopen("in.txt", "r", stdin) const ll INFll = 0x3f3f3f3f3f3f3f3fLL; const int INF= 0x7ffffff; const int mod = 1000000007; struct point{ double x,y; }p[60]; int n; double dp[60][60]; double area(point a,point b,point c){ return abs((b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y))/2.0; } int judge(int a,int b,int c){ for(int i=0;i<n;++i){ if(i!=a&&i!=b&&i!=c){ double tmp=area(p[a],p[b],p[i])+area(p[a],p[i],p[c])+area(p[i],p[b],p[c]); if(abs(tmp-area(p[a],p[b],p[c]))<1e-6) return 0; } } return 1; } void solve(){ double minv=INF; for(int l=2;l<n;++l) for(int i=0;i<n;++i){ int j=(i+l)%n; dp[i][j]=INF; for(int k=(i+1)%n;k!=j;k=(k+1)%n){ if(judge(i,k,j)){ dp[i][j]=min(dp[i][j],max(max(dp[i][k],dp[k][j]),area(p[i],p[k],p[j]))); } } if(l==n-1) minv=min(minv,dp[i][j]); } printf("%.1lf\n",minv); } int main() { int t; scanf("%d",&t); while(t--){ scanf("%d",&n); for(int i=0;i<n;++i) scanf("%lf%lf",&p[i].x,&p[i].y); solve(); } return 0; }
时间: 2024-10-16 13:46:47