由于题目要求,首先维护出一个凸包,然后在凸包上寻找点对关系,用rel[i][j]表示i点和j点之间是否可以连线,又由于维护出来的凸包上的点的个数不多,可以直接枚举点对并枚举所有圆,判断两点直线和圆是否相离,由于维护出来的凸包已经按照逆时针排序,又要满足两两线段不相交,最后就变成了求最大不相交线段个数,但是可以包含(2-5线段可以包含3-4,但是不能选择3-6),然后考虑区间DP去枚举所有情况,设dp[s][t]表示起点在s终点在t之间的区间内的最大不相交线段个数,枚举终点和起点,再枚举起点到终点内的点i,由于可以包含,则转移为dp[s][t]=max(dp[s][t],dp[s][i]+rel[s%n][t%n]),最后查询答案枚举所有长度为n的区间的最值即可。

 //        ——By DD_BOND

 //#include<bits/stdc++.h>
//#include<unordered_map>
//#include<unordered_set>
#include<functional>
#include<algorithm>
#include<iostream>
//#include<ext/rope>
#include<iomanip>
#include<climits>
#include<cstring>
#include<cstdlib>
#include<cstddef>
#include<cstdio>
#include<memory>
#include<vector>
#include<cctype>
#include<string>
#include<cmath>
#include<queue>
#include<deque>
#include<ctime>
#include<stack>
#include<map>
#include<set> #define fi first
#define se second
#define pb push_back typedef long long ll; using namespace std; const int MAXN=1e3+;
const double eps=1e-;
const double pi=acos(-1.0);
const ll INF=0x3f3f3f3f3f3f3f3f; inline int dcmp(double x){
if(fabs(x)<eps) return ;
return (x>? : -);
} inline double sqr(double x){ return x*x; } struct Point{
double x,y;
Point(){ x=,y=; }
Point(double _x,double _y):x(_x),y(_y){}
void input(){ scanf("%lf%lf",&x,&y); }
void output(){ printf("%.2f %.2f\n",x,y); }
friend istream &operator >>(istream &os,Point &b){
os>>b.x>>b.y;
return os;
}
friend ostream &operator <<(ostream &os,Point &b){
os<<b.x<<' '<<b.y;
return os;
}
bool operator ==(const Point &b)const{
return (dcmp(x-b.x)==&&dcmp(y-b.y)==);
}
bool operator !=(const Point &b)const{
return !((dcmp(x-b.x)==&&dcmp(y-b.y)==));
}
bool operator <(const Point &b)const{
return (dcmp(x-b.x)==? dcmp(y-b.y)< : x<b.x);
}
double operator ^(const Point &b)const{ //叉积
return x*b.y-y*b.x;
}
double operator *(const Point &b)const{ //点积
return x*b.x+y*b.y;
}
Point operator +(const Point &b)const{
return Point(x+b.x,y+b.y);
}
Point operator -(const Point &b)const{
return Point(x-b.x,y-b.y);
}
Point operator *(double a){
return Point(x*a,y*a);
}
Point operator /(double a){
return Point(x/a,y/a);
}
double len2(){ //长度平方
return sqr(x)+sqr(y);
}
double len(){ //长度
return sqrt(len2());
}
double polar(){ //向量的极角
return atan2(y,x); //返回与x轴正向夹角(-pi~pi]
}
Point change_len(double r){ //转化为长度为r的向量
double l=len();
if(dcmp(l)==) return *this; //零向量
return Point(x*r/l,y*r/l);
}
Point rotate_left(){ //逆时针旋转90度
return Point(-y,x);
}
Point rotate_right(){ //顺时针旋转90度
return Point(y,-x);
}
Point rotate(Point p,double ang){ //绕点p逆时针旋转ang度
Point v=(*this)-p;
double c=cos(ang),s=sin(ang);
return Point(p.x+v.x*c-v.y*s,p.y+v.x*s+v.y*c);
}
Point normal(){ //单位化,逆时针旋转90°
return Point(-y/len(),x/len());
}
}; inline double cross(Point a,Point b){ //叉积
return a.x*b.y-a.y*b.x;
} inline double dis(Point a,Point b){ //两点的距离
Point p=b-a; return p.len();
} struct Line{
Point s,e;
Line(){}
Line(Point _s,Point _e):s(_s),e(_e){} //两点确定直线
double length(){ //线段长度
return dis(s,e);
}
}; double point_to_line(Point p,Line a){ //点到直线距离
return fabs(cross(p-a.s,a.e-a.s)/a.length());
} struct Circle{
Point p;
double r;
Circle(){}
Circle(Point _p,double _r):p(_p),r(_r){}
}; int relation(Line a,Circle b){ //直线和圆的位置关系 0:相离 1:相切 2:相交
double p=point_to_line(b.p,a);
if(dcmp(p-b.r)==) return ;
return (dcmp(p-b.r)<? : );
} Point tmp[];
int convex_hull(Point *p,int n,Point *ch){ //求凸包
int m=;
sort(p,p+n);
for(int i=;i<n;i++){
while(m>&&dcmp(cross(tmp[m-]-tmp[m-],p[i]-tmp[m-]))<=) m--;
tmp[m++]=p[i];
}
int k=m;
for(int i=n-;i>=;i--){
while(m>k&&dcmp(cross(tmp[m-]-tmp[m-],p[i]-tmp[m-]))<=) m--;
tmp[m++]=p[i];
}
if(n>) m--;
for(int i=;i<m;i++) ch[i]=tmp[i];
return m;
} int dp[][];
Point point[];
Circle circle[];
bool rel[][]; int main(void){
int T; scanf("%d",&T);
while(T--){
memset(dp,,sizeof(dp));
memset(rel,,sizeof(rel));
int n,m,ans=; double r; scanf("%d%d%lf",&n,&m,&r);
for(int i=;i<n;i++) point[i].input();
for(int i=;i<m;i++) circle[i].p.input(),circle[i].r=r;
n=convex_hull(point,n,point);
for(int i=;i<n;i++)
for(int j=i+;j<n-(i==);j++){
int flag=;
for(int z=;z<m;z++)
if(relation(Line(point[i],point[j]),circle[z])){
flag=;
break;
}
if(flag) rel[i][j]=rel[j][i]=;
}
for(int t=;t<*n;t++)
for(int s=max(,t-n+);s<=t;s++)
for(int i=t;i>=s;i--)
dp[s][t]=max(dp[s][t],dp[s][i]+rel[s%n][t%n]);
for(int i=n-;i<*n;i++) ans=max(ans,dp[i-n+][i]);
printf("%d\n",ans);
}
return ;
}

最新文章

  1. 【Linux】虚拟机安装Archlinux
  2. 学习微信小程序之css9内边距
  3. Decimal To Fraction 小数转换成分数
  4. CRM客户关系管理系统修改(十四)
  5. 移植u-boot-1.1.6之mtdparts分区
  6. POJ3616 Milking Time 简单DP
  7. 转载最佳JQuery学习网站
  8. [置顶] 第二届微软CRM交流年会
  9. ubuntu安装aircrack-ng/reaver/minidwep-gtk用来跑pin
  10. oracle表连接------&amp;gt;排序合并连接(Merge Sort Join)
  11. Express + Session 实现登录验证
  12. Django admin自定制功能
  13. IIC_slaver 仿真错误
  14. Transaction rolled back because it has been marked as rollback-only
  15. SpringBoot整合ssm
  16. I - All X
  17. MVC 简介
  18. ssh免密登陆权限问题
  19. 【转】MySQL执行计划分析
  20. iview 下拉刷新loadTop报错解决

热门文章

  1. python frozenset集合(17)
  2. celery结合redis 使用
  3. maven整合eclise
  4. Java中日期
  5. CF G. Orientation of Edges BFS
  6. 2017乌鲁木齐网络赛 J题 Our Journey of Dalian Ends ( 最小费用最大流 )
  7. 贪心整理&amp;一本通1431:钓鱼题解
  8. android 开发,视频群聊引发短信异常
  9. SpringBoot项目的前端+thymeleaf模板引擎
  10. Window7系统安装Ubuntu16双系统