由于题目要求,首先维护出一个凸包,然后在凸包上寻找点对关系,用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 ;
}

HDU 6603 Azshara's deep sea(凸包+区间DP)的更多相关文章

  1. [hdu contest 2019-07-29] Azshara's deep sea 计算几何 动态规划 区间dp 凸包 graham扫描法

    今天hdu的比赛的第一题,凸包+区间dp. 给出n个点m个圆,n<400,m<100,要求找出凸包然后给凸包上的点连线,连线的两个点不能(在凸包上)相邻,连线不能与圆相交或相切,连线不能相 ...

  2. [2019HDU多校第三场][HDU 6603][A. Azshara's deep sea]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6603 题目大意:给出一个凸包,凸包内有若干个圆,要求画尽可能多的对角线使得他们两两不在凸包内相交且不与 ...

  3. HDU 6212 Zuma 2017青岛网络赛 区间DP

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6212 解法:看了眼题就发现这个BZOJ 1032不是一毛一样?但是BZOJ上那是个巨坑,数据有错,原来 ...

  4. HDU 4283 You Are the One(区间DP(最优出栈顺序))

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4283 题目大意:有一群屌丝,每个屌丝有个屌丝值,如果他第K个上场,屌丝值就为a[i]*(k-1),通过 ...

  5. ZOJ 3537 Cake(凸包+区间DP)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3537 题目大意:给出一些点表示多边形顶点的位置,如果不是凸多边形 ...

  6. ZOJ 3537 Cake 求凸包 区间DP

    题意:给出一些点表示多边形顶点的位置(如果多边形是凹多边形就不能切),切多边形时每次只能在顶点和顶点间切,每切一次都有相应的代价.现在已经给出计算代价的公式,问把多边形切成最多个不相交三角形的最小代价 ...

  7. HDU 4283 You Are the One 【区间DP】

    <题目链接> 题目大意: 有$n$个人排成一排要上台表演,每个人有一个屌丝值$pi$.第i个上台表演的人,他的不满意度为$(i-1)*p_i$.现在有一个类似于栈的黑屋子,你可以让某些人进 ...

  8. HDU 4597 Play Game(DFS,区间DP)

    Play Game Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others) Total Sub ...

  9. HDU 1506 Largest Rectangle in a Histogram(区间DP)

    题目网址:http://acm.hdu.edu.cn/showproblem.php?pid=1506 题目: Largest Rectangle in a Histogram Time Limit: ...

随机推荐

  1. Tengine + Lua + GraphicsMagick 实现图片自动裁剪/缩放

    http://my.oschina.net/eduosi/blog/169606

  2. css 3D动画

    一.今天让我们来学习一下css 3D吧! 1.首先我们要学习好css3 3d一定要有一定的立体感! 2.再来那就聊聊原理吧! 3.css3 3d 顾名思义是由两个2d名片组成的 但不是让你建立连个2d ...

  3. day5 函数

      1.求全部元素的和 [1,2,1,2,3,3,3,3] 遍历 a = [1,2,1,2,3,3,3,3] sum = 0 n = len(a)-1 while n>=0: sum += a[ ...

  4. 【GDOI2014模拟】服务器

    前言 直到比赛最后几分钟,才发现60%数据居然是一个水dp,结果没打完. 题目 我们需要将一个文件复制到n个服务器上,这些服务器的编号为S1, S2, -, Sn. 首先,我们可以选择一些服务器,直接 ...

  5. 【leetcode】523. Continuous Subarray Sum

    题目如下: 解题思路:本题需要用到这么一个数学定理.对于任意三个整数a,b,k(k !=0),如果 a%k = b%k,那么(a-b)%k = 0.利用这个定理,我们可以对数组从头开始进行求和,同时利 ...

  6. STM32内部时钟设置-寄存器版

    STM32寄存器版本——内部时钟设置 同时要记得把延时初始化函数设置好 //系统时钟初始化函数 //pll:选择的倍频数,从2开始,最大值为16 //pll:选择的倍频数,这里使用内部时钟,PLL为4 ...

  7. Java——容器

    [容器API]    <1>J2SDK所提供的容器位于java.util包内.  

  8. formdata方式上传文件,支持大文件分割上传

    1.upload.html <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/html"> <h ...

  9. [spring cloud feign] [bug] 使用对象传输get请求参数

    前言 最近在研究 srping cloud feign ,遇到了一个问题,就是当 get 请求 的参数使用对象接收时,就会进入熔断返回.经过百度,发现网上大部分的解决方案都是将请求参数封装到Reque ...

  10. [CSP-S模拟测试]:计数(DP+记忆化搜索)

    题目描述 既然是萌萌哒$visit\text{_}world$的比赛,那必然会有一道计数题啦!考虑一个$N$个节点的二叉树,它的节点被标上了$1\sim N$的编号.并且,编号为$i$的节点在二叉树的 ...