Topic links: http://acm.hdu.edu.cn/showproblem.php?pid=6603
Title effect: given a convex hull, with a plurality of convex round bag, draw as much as possible requires that the diagonals intersect the convex hull does not twenty-two not with any of a circle with a common point
Solution: whether the connection between the first pre-processing for all points on a common circle and would point, denoted x [i] [j], followed by the interval DP. Set f [i] [d] represents from \ (I \) points to \ (i + d \) drawn up to the diagonal point how many of the intervals, then there is \ (f [i] maximum [d] = x [i] + max (f [i] [d-1], f [i + 1] [d-1]) \), the answer to take [nxt] f [i] [d] of value can be
Complexity Analysis: seek convex hull \ (O (nlogn) \), pretreatment \ (O (n ^ 2g) \), DP \ (O (n ^ 2) \), the total time complexity is \ (O ( n ^ 2g) \)
Tucao: this question long and stinking face the question, seriously affect the viewing experience
Given \ (n \) points is not necessarily a vertex of the convex hull, so we have to find a convex hull, but such an important condition is actually hidden in a small parenthesis face huge problems in the pits a lot of people
The last three minutes to discover this hidden conditions, and quickly pulled out a template last tune various parameters passed orz finally burst at the last minute ...
#include<bits/stdc++.h> using namespace std; #define N 401 #define LL long long const double eps=1e-9; int sgn(double x) { if (x<-eps) return -1; if (x>eps) return 1; return 0; } struct Point { double x,y; void read(){scanf("%lf%lf",&x,&y);} Point operator -(const Point &t)const{return {x-t.x,y-t.y};} double operator *(const Point &t)const{return x*t.y-y*t.x;} double length()const{return sqrt(x*x+y*y);} double ang()const { return atan2(1.0*y,1.0*x); } }b[N]; Point cent; bool cmpang(const Point &p1,const Point &p2) { int tmp=sgn( (p1-cent).ang() - (p2-cent).ang() ); if (tmp!=0) return tmp<0; return (p1-cent).length() < (p2-cent).length(); } struct POLYGON { int n; Point a[N]; void ChangetoConvex() { for (int i=2;i<=n;i++) if (a[i].x<a[1].x||a[i].x==a[1].x&&a[i].y<a[1].y) swap(a[1],a[i]); cent=a[1]; sort(a+2,a+n+1,cmpang); int top=2; for (int i=3;i<=n;i++) { while(top>=2&& (a[top]-a[top-1])*(a[i]-a[top])<=0 ) top--; a[++top]=a[i]; } n=top; } }P; int T,n,g,r,x[N][N],f[N][N]; bool check(int x,int y) { if(x%n+1==y || y%n+1==x) return false; double dis=(P.a[x]-P.a[y]).length(); for(int i=1;i<=g;i++) { double cha=abs((P.a[y]-P.a[x])*(b[i]-P.a[x])); if(cha+eps<=1.0*r*dis)return false; } return true; } void init() { int ans=0; memset(f,0,sizeof(f)); scanf("%d%d%d",&n,&g,&r); P.n=n; for(int i=1;i<=n;i++) P.a[i].read(); for(int i=1;i<=g;i++) b[i].read(); P.ChangetoConvex(); n=P.n; for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++) x[i][j]=x[j][i]=check(i,j); for(int d=2;d<=n-2;d++) for(int i=1;i<=n;i++) { int nxt=(i+d-1)%n+1,res=0; res=max(f[i][d-1],f[i%n+1][d-1]); f[i][d]=x[i][nxt]+res; ans=max(ans,f[i][d]); } printf("%d\n",ans); } int main() { scanf("%d",&T); while(T--)init(); }