HDU 6603 Azshara's deep sea(凸包+区间DP)
由于题目要求,首先维护出一个凸包,然后在凸包上寻找点对关系,用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)的更多相关文章
- [hdu contest 2019-07-29] Azshara's deep sea 计算几何 动态规划 区间dp 凸包 graham扫描法
今天hdu的比赛的第一题,凸包+区间dp. 给出n个点m个圆,n<400,m<100,要求找出凸包然后给凸包上的点连线,连线的两个点不能(在凸包上)相邻,连线不能与圆相交或相切,连线不能相 ...
- [2019HDU多校第三场][HDU 6603][A. Azshara's deep sea]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6603 题目大意:给出一个凸包,凸包内有若干个圆,要求画尽可能多的对角线使得他们两两不在凸包内相交且不与 ...
- HDU 6212 Zuma 2017青岛网络赛 区间DP
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6212 解法:看了眼题就发现这个BZOJ 1032不是一毛一样?但是BZOJ上那是个巨坑,数据有错,原来 ...
- HDU 4283 You Are the One(区间DP(最优出栈顺序))
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4283 题目大意:有一群屌丝,每个屌丝有个屌丝值,如果他第K个上场,屌丝值就为a[i]*(k-1),通过 ...
- ZOJ 3537 Cake(凸包+区间DP)
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3537 题目大意:给出一些点表示多边形顶点的位置,如果不是凸多边形 ...
- ZOJ 3537 Cake 求凸包 区间DP
题意:给出一些点表示多边形顶点的位置(如果多边形是凹多边形就不能切),切多边形时每次只能在顶点和顶点间切,每切一次都有相应的代价.现在已经给出计算代价的公式,问把多边形切成最多个不相交三角形的最小代价 ...
- HDU 4283 You Are the One 【区间DP】
<题目链接> 题目大意: 有$n$个人排成一排要上台表演,每个人有一个屌丝值$pi$.第i个上台表演的人,他的不满意度为$(i-1)*p_i$.现在有一个类似于栈的黑屋子,你可以让某些人进 ...
- HDU 4597 Play Game(DFS,区间DP)
Play Game Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others) Total Sub ...
- HDU 1506 Largest Rectangle in a Histogram(区间DP)
题目网址:http://acm.hdu.edu.cn/showproblem.php?pid=1506 题目: Largest Rectangle in a Histogram Time Limit: ...
随机推荐
- LOJ 6192 城市网络(树上倍增)
LOJ #6192. 「美团 CodeM 复赛」城市网络(链接) 一棵以 $ 1 $ 号节点为根的树,每个点有一个权值,有 $ q $ 个询问,每次从 $ x $ 点开始往某个祖先 $ y $ 走,初 ...
- ubuntu16.04 安装mysql
安装mysql 1.sudo apt-get install mysql-server 2.sudo apt install mysql-client 3.sudo apt install libmy ...
- 【python实例】判断质数:for-break-else
""" for 变量 in 容器: 遍历--break 如果执行到了break语句, 则else不会被执行 else: break语句没有被执行时, 执行else &qu ...
- __new__与__init__的区别
__new__ : 控制对象的实例化过程 , 在__init__方法之前调用 __init__ : 对象实例化对象进行属性设置 class User: def __new__(cls, *args, ...
- mysql CREATE TABLE语句 语法
mysql CREATE TABLE语句 语法 作用:创建数据库中的表. 大理石量具系列 语法:CREATE TABLE 表名称 (列名称1 数据类型,列名称2 数据类型,列名称3 数据类型,.... ...
- PHP 大文件上传进度条实现
核心原理: 该项目核心就是文件分块上传.前后端要高度配合,需要双方约定好一些数据,才能完成大文件分块,我们在项目中要重点解决的以下问题. * 如何分片: * 如何合成一个文件: * 中断了从哪个分片开 ...
- Internet History, Technology, and Security(week7)——Technology: Application Protocols
Layer 4: Applications Application Layer TCP提供了“a reliable pipe”(一个坚固的水管)连接用户和服务器,确保了数据能准确不出意外地传输,所以A ...
- RabbitMQ绑定、队列、消息、虚拟主机详解(五)
Binding:绑定,Exchange和Exchange.Queue之间的连接关系 Binding中可以包含RoutingKey或者参数 Queue:消息队列,实际存储消息数据 Durability: ...
- WWDC2017-whats_new_in_safari_view_controller
最后更新: 2017-08-08 官方地址: https://developer.apple.com/videos/play/wwdc2017/225/ WWDC2017中,对SafariViewCo ...
- 7月清北学(zao)堂系列
7.13:模拟,贪心(贪心题大赏),考试 7.14:分治,分块,搜索(大法师大法好),数论 7.15:数据结构(树状数组,线段树,),ST表,树上倍增求LCA 7.16:图论题大赏(分层建图神马的), ...