题意不多说
题解:
这道题的dp题非常好,方程式的定义看似简单,但其实很难想到
dp[i][j]表示编号从i到j的点构成的多边形中的最大三角形面积
注意到这一点,这个图是封闭的,也就是一个环状,所以不能忽略掉如dp[n][1]这种情况
解决方法就是mod n
在根据一系列几何知识: dp[i][j] = max( dp[i][k], dp[k][j], S(i,j,k);(S是三点围成的面积)
然后对于凹多边形,要判断三角形是否存在,可以转化成是否有点在三角形的内部,若存在,此三角形就不存在
code:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
const int MAXN=55;
const double esp=1e-9;
const int inf=0x3f3f3f3f;
using namespace std;
struct node{int x,y;}p[MAXN];
int n; double dp[MAXN][MAXN];
inline double S(int t1,int t2,int t3){
return fabs((p[t2].x-p[t1].x)*(p[t3].y-p[t1].y)-(p[t3].x-p[t1].x)*(p[t2].y-p[t1].y))*0.5;
}
bool inarea(int t1,int t2,int t3){
double cmp1=S(t1,t2,t3);
for(int i=0;i<n;i++)
{
if(i==t1||i==t2||i==t3) continue;
double cmp2=S(t1,t2,i)+S(t2,t3,i)+S(t1,t3,i);
if(fabs(cmp1-cmp2)<=esp) return 0;
}
return 1;
}
int main()
{
int T; scanf("%d",&T); while(T--)
{
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&p[i].x);
scanf("%d",&p[i].y);
}
for(int i=0;i<2;i++)
for(int j=0;j<n;j++)
dp[i][(j+i)%n]=0;
for(int i=0;i<n;i++)
dp[i][(i+2)%n]=S(i,(i+1)%n,(i+2)%n);
for(int l=3;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(inarea(i,j,k))
dp[i][j]=min(dp[i][j],max(max(dp[i][k],dp[k][j]),S(i,j,k)));
}
double ans=inf;
for(int i=0;i<n;i++)
ans=min(ans,dp[i][(i+n-1)%n]);
printf("%.1lf\n",ans);
}
}