[2019HDU multi-school third] [HDU 6603] [A. Azshara's deep sea]

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();
}
View Code

 

Guess you like

Origin www.cnblogs.com/DeaphetS/p/11265399.html
Recommended