hdu 1966 Minimax Triangulation

来源:互联网 发布:js添加隐藏属性 编辑:程序博客网 时间:2024/04/30 19:12

咱其实最讨厌图论了 =.=  写这道题简直蛋疼。

给予一个多边形,对其进行三角分割后最大的那个三角形的面积最小值为多少。

像这种肯定是<贪心、DP、搜索>中的一种,贪心么没什么直观的规律用不了,搜索的话虽然多边形的点少(3<=n<=50)但是时间复杂度肯定过不去,后来也想了一下,用记忆化搜索,不过中间状态想不出好方法记录,所以最后想想还是用DP了。

嘛,用DP的时候直接就想成dp[L][R]代表从第L个顶点到第R个顶点的最优分割值,这样的话递推公式也出来了dp[L][R]=min{   max(  dp[L][Mid]  , dp[Mid][R]  ,Δ(L,Mid,R) )   ,    L <  Mid < R  }(相当于把多边形分割为多边形L~Mid,多边形Mid~R,和一个三角形(L,Mid,R)这样三块)。

考虑到这样分割后都是连续点连成的多边形,可能会漏掉那些非连续的情况。但是后来想了想,连续的情况是可以组成那些非连续的情况的。那就不用加以处理。

恩,这样应该是没问题了,然后交了一发,WA。又不停的改细节,交了5发,全WA。卧槽怎么可能?(╯‵□′)╯︵┻━┻(掀桌)

然后看了下题目的测试例子,可能会出现凹多边形(笑)。

好吧,那就改,怎么改呢。就是排除掉那些违规分割。例如这种:

这种Δ(L,Mid,R) 就是违规分割的,因为其中还包含了其他另外的顶点。那问题就在于判断是否有顶点处于三角形之中,这个用叉积也可以判断就不说了。

我只想说,代码写的简直难看。



#include <stdio.h>#include <algorithm>using namespace std;const int MAXM = 61;const int INF = 0x3f3f3f3f;int dp[MAXM][MAXM];int Num;int Clock;int X[MAXM];int Y[MAXM];int Calcu(int a,int b,int c){int x1=X[b]-X[a];int x2=X[c]-X[a];int y1=Y[b]-Y[a];int y2=Y[c]-Y[a];return Clock*(x1*y2-y1*x2);}void Judge(){int sum=0;Clock=1;for(int i=2;i<Num;i++){sum+=Calcu(1,i,i+1);}if(sum<0)Clock=-1;}void Read_Case(){scanf("%d",&Num);for(int i=1;i<=Num;i++){scanf("%d %d",X+i,Y+i);}}bool Edge(int a,int b,int c){int i;int ans=abs((int)Calcu(a,b,c));for(i=1;i<=Num;i++){if(i==a||i==b||i==c)continue;if(ans==abs((int)Calcu(i,b,c))+abs((int)Calcu(i,b,a))+abs((int)Calcu(i,a,c)))break;}if(i>Num)return 0;return 1;}void Deal(){for(int i=1;i<=Num;i++)dp[i][i]=0;for(int i=1;i<Num;i++)dp[i][i+1]=0;for(int i=1;i<=Num-2;i++){dp[i][i+2]=Calcu(i,i+1,i+2);}int R,L,Mid,Limit,Ans;for(int dis=3;dis<Num;dis++){Limit=Num-dis;for(L=1;L<=Limit;L++){R=L+dis;dp[L][R]=INF;for(Mid=L;Mid<=R;Mid++){if(Edge(L,Mid,R))continue;Ans=max(Calcu(L,Mid,R),max(dp[L][Mid],dp[Mid][R]));dp[L][R]=min(dp[L][R],Ans);}}}printf("%.1lf\n",dp[1][Num]/2.0);}int main(){int T;scanf("%d",&T);while(T--){Read_Case();Judge();Deal();}}


要死要死   什么东西扯个图上来就想老半天 = =


0 0
原创粉丝点击