POJ3178 计算几何+DP

 1 //一些点一些圆,过圆不能连线,相邻点不能连线,问最多连几条线 
 2 //计算几何模板+区间dp
 3 //关键是判断圆和线段是否相交 
 4 #include <cstdio>
 5 #include <cmath>
 6 #include <algorithm>
 7 #define N 500
 8 #define ll long long
 9 #define sqr(x) ((x)*(x))
10 using namespace std;
11 bool ok[N][N];
12 ll n,m,r,f[N][N];
13 struct poi
14 {
15     ll x,y;
16     poi(ll X,ll Y)
17     {
18         x=X;y=Y;
19     }
20     poi()
21     {
22     }
23 } p[N],q[N];
24 ll cro(poi a,poi b)
25 {
26     return (a.x*b.y-a.y*b.x);
27 }
28 ll dot(poi a,poi b)
29 {
30     return a.x*b.x+a.y*b.y;
31 }
32 poi tr(poi a,poi b)
33 {
34     return poi(a.x-b.x,a.y-b.y);
35 }
36 double dis(poi a,poi b)
37 {
38     return sqrt((double)(sqr(a.x-b.x)+sqr(a.y-b.y)));
39 }
40 bool cmp(poi a,poi b)
41 {
42     return (a.x<b.x)||(a.x==b.x && a.y<b.y);
43 }
44 bool cmp2(poi a,poi b)
45 {
46     return cro(tr(a,p[1]),tr(b,p[1]))>0;
47 }
48 bool check(poi a,poi b)
49 {
50     double C=dis(a,b);
51     for(int i=1;i<=m;i++)
52     {
53         double A=dis(q[i],a);
54         double B=dis(q[i],b);
55         double COSA=(B*B+C*C-A*A)/(2*B*C);
56         double COSB=(A*A+C*C-B*B)/(2*A*C);
57         if(COSA<1e-10||COSB<1e-10){
58             if(A<1.0*r+1e-10||B<1.0*r+1e-10)return 0;
59             else continue;
60         }
61         double SINA=sqrt(1-COSA*COSA);
62         double H=B*SINA;
63         if(H<1.0*r+1e-10)return 0;
64     }
65     return 1;
66 }
67 int main()
68 {
69     scanf("%d%d%d",&n,&m,&r);
70     for(int i=1;i<=n;i++)
71         scanf("%d%d",&p[i].x,&p[i].y);
72     sort(p+1,p+1+n,cmp);
73     sort(p+2,p+1+n,cmp2);
74     for(int i=1;i<=m;i++)
75         scanf("%d%d",&q[i].x,&q[i].y);
76     for(int i=1;i<=n;i++)
77         for(int j=i+2;j<=n;j++)
78         if(i!=1 || j!=n)
79             ok[i][j]=check(p[i],p[j]);
80     for(int len=2;len<=n;len++)
81         for(int start=1;start<=n;start++){
82             ll end=start+len;
83             for(int k=start+1;k<min(end,n);k++)
84                 f[start][end]=max(f[start][end],f[start][k]+f[k][end]);
85             f[start][end]+=ok[start][end];
86         }
87     printf("%d\n",f[1][n]);
88 }

 

posted @ 2017-07-09 20:56  汪立超  阅读(249)  评论(0编辑  收藏  举报