Online Judge | Problem Set | Authors | Online Contests | User | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest |
这么做/* 枚举左下角 然后f[i][j]用来表示以点i,点j为凸包最后两个点的最大面积 */ #include<iostream> using namespace std; #define maxn 101 #define sqr(x) ((x)*(x)) #define Inf 1e30 inline int Cross_Product(int x_1,int y_1,int x_2,int y_2) { return x_1*y_2-x_2*y_1; } struct Point { int x,y; void Readin() { scanf("%d%d",&x,&y); } void Minus(Point s) { x-=s.x,y-=s.y; } bool In(Point a,Point b) { int r1=Cross_Product(-x,-y,a.x-x,a.y-y); int r2=Cross_Product(a.x-x,a.y-y,b.x-x,b.y-y); int r3=Cross_Product(b.x-x,b.y-y,-x,-y); return (r1>0 && r2>0 && r3>0 || r1<0 && r2<0 && r3<0); } } p[maxn],q[maxn],s; int n,m; bool done[maxn][maxn]; double ans,rec[maxn][maxn]; int Compare_Horizontal(const void *a,const void *b) { if (((Point*)a)->y==((Point*)b)->y) return ((Point*)a)->x-((Point*)b)->x; return ((Point*)a)->y-((Point*)b)->y; } int Compare_Angle(const void *a,const void *b) { int x_1=((Point*)a)->x,y_1=((Point*)a)->y; int x_2=((Point*)b)->x,y_2=((Point*)b)->y; int tmp=Cross_Product(x_1,y_1,x_2,y_2); if (tmp) return -tmp; return -( sqr(x_1)+sqr(y_1)-sqr(x_2)-sqr(y_2) ); } void Init() { //读入并且排水平序 scanf("%d",&n); for (int i=0; i<n; i++) p[i].Readin(); qsort(p,n,sizeof(Point),Compare_Horizontal); ans=0.0; } double f(int i,int j) { if (done[i][j]) return rec[i][j]; done[i][j]=true; for (int k=i+1; k<j; k++) //判断状态是否合法 if (q[k].In(q[i],q[j])) { rec[i][j]=-Inf; return rec[i][j]; } rec[i][j]=Cross_Product(q[i].x,q[i].y,q[j].x,q[j].y)*0.5; //向前转移 if (!Cross_Product(q[i].x,q[i].y,q[j].x,q[j].y) || Cross_Product(q[i].x,q[i].y,q[i+1].x,q[i+1].y)) { double tmp=0.0; for (int k=0; k<i; k++) if (Cross_Product(q[i].x-q[j].x,q[i].y-q[j].y,q[k].x-q[i].x,q[k].y-q[i].y)<=0) tmp>?=f(k,i); rec[i][j]+=tmp; } return rec[i][j]; } void Dp() { memset(done,0,sizeof(done)); memset(rec,0,sizeof(rec)); for (int i=0; i<m-1; i++) for (int j=i+1; j<m; j++) ans>?=f(i,j); } void Work() { //枚举凸包的左下角 for (int i=0; i<n-2; i++) { s=p[i]; m=n-1-i; for (int j=0; j<m; j++) q[j]=p[j+i+1]; for (int j=0; j<m; j++) q[j].Minus(s); //把后面的点都拿出来,再排极角序 qsort(q,m,sizeof(Point),Compare_Angle); Dp(); //动态规划 } } int main() { int test; for (scanf("%d",&test); test; test--) { Init(); Work(); printf("%.1lf\n",ans); } return 0; } Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator