zoukankan      html  css  js  c++  java
  • 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的区间的最值即可。

      1 //        ——By DD_BOND
      2 
      3 //#include<bits/stdc++.h>
      4 //#include<unordered_map>
      5 //#include<unordered_set>
      6 #include<functional>
      7 #include<algorithm>
      8 #include<iostream>
      9 //#include<ext/rope>
     10 #include<iomanip>
     11 #include<climits>
     12 #include<cstring>
     13 #include<cstdlib>
     14 #include<cstddef>
     15 #include<cstdio>
     16 #include<memory>
     17 #include<vector>
     18 #include<cctype>
     19 #include<string>
     20 #include<cmath>
     21 #include<queue>
     22 #include<deque>
     23 #include<ctime>
     24 #include<stack>
     25 #include<map>
     26 #include<set>
     27 
     28 #define fi first
     29 #define se second
     30 #define pb push_back
     31 
     32 typedef long long ll;
     33 
     34 using namespace std;
     35 
     36 const int MAXN=1e3+10;
     37 const double eps=1e-10;
     38 const double pi=acos(-1.0);
     39 const ll INF=0x3f3f3f3f3f3f3f3f;
     40 
     41 inline int dcmp(double x){
     42     if(fabs(x)<eps)    return 0;
     43     return (x>0? 1: -1);
     44 }
     45 
     46 inline double sqr(double x){ return x*x; }
     47 
     48 struct Point{
     49     double x,y;
     50     Point(){ x=0,y=0; }
     51     Point(double _x,double _y):x(_x),y(_y){}
     52     void input(){ scanf("%lf%lf",&x,&y); }
     53     void output(){ printf("%.2f %.2f
    ",x,y); }
     54     friend istream &operator >>(istream &os,Point &b){
     55         os>>b.x>>b.y;
     56         return os;
     57     }
     58     friend ostream &operator <<(ostream &os,Point &b){
     59         os<<b.x<<' '<<b.y;
     60         return os;
     61     }
     62     bool operator ==(const Point &b)const{
     63         return (dcmp(x-b.x)==0&&dcmp(y-b.y)==0);
     64     }
     65     bool operator !=(const Point &b)const{
     66         return !((dcmp(x-b.x)==0&&dcmp(y-b.y)==0));
     67     }
     68     bool operator <(const Point &b)const{
     69         return (dcmp(x-b.x)==0? dcmp(y-b.y)<0 : x<b.x);
     70     }
     71     double operator ^(const Point &b)const{        //叉积
     72         return x*b.y-y*b.x;
     73     }
     74     double operator *(const Point &b)const{        //点积
     75         return x*b.x+y*b.y;
     76     }
     77     Point operator +(const Point &b)const{
     78         return Point(x+b.x,y+b.y);
     79     }
     80     Point operator -(const Point &b)const{
     81         return Point(x-b.x,y-b.y);
     82     }
     83     Point operator *(double a){
     84         return Point(x*a,y*a);
     85     }
     86     Point operator /(double a){
     87         return Point(x/a,y/a);
     88     }
     89     double len2(){    //长度平方
     90         return sqr(x)+sqr(y);
     91     }
     92     double len(){   //长度
     93         return sqrt(len2());
     94     }
     95     double polar(){    //向量的极角
     96         return atan2(y,x);     //返回与x轴正向夹角(-pi~pi]
     97     }
     98     Point change_len(double r){    //转化为长度为r的向量
     99         double l=len();
    100         if(dcmp(l)==0)    return *this;  //零向量
    101         return Point(x*r/l,y*r/l);
    102     }
    103     Point rotate_left(){    //逆时针旋转90度
    104         return Point(-y,x);
    105     }
    106     Point rotate_right(){    //顺时针旋转90度
    107         return Point(y,-x);
    108     }
    109     Point rotate(Point p,double ang){    //绕点p逆时针旋转ang度
    110         Point v=(*this)-p;
    111         double c=cos(ang),s=sin(ang);
    112         return Point(p.x+v.x*c-v.y*s,p.y+v.x*s+v.y*c);
    113     }
    114     Point normal(){        //单位化,逆时针旋转90°
    115         return Point(-y/len(),x/len());
    116     }
    117 };
    118 
    119 inline double cross(Point a,Point b){    //叉积
    120     return a.x*b.y-a.y*b.x;
    121 }
    122 
    123 inline double dis(Point a,Point b){    //两点的距离
    124     Point p=b-a;    return p.len();
    125 }
    126 
    127 struct Line{
    128     Point s,e;
    129     Line(){}
    130     Line(Point _s,Point _e):s(_s),e(_e){} //两点确定直线
    131     double length(){    //线段长度
    132         return dis(s,e);
    133     }
    134 };
    135 
    136 double point_to_line(Point p,Line a){    //点到直线距离
    137     return fabs(cross(p-a.s,a.e-a.s)/a.length());
    138 }
    139 
    140 struct Circle{
    141     Point p;
    142     double r;
    143     Circle(){}
    144     Circle(Point _p,double _r):p(_p),r(_r){}
    145 };
    146 
    147 int relation(Line a,Circle b){    //直线和圆的位置关系  0:相离   1:相切   2:相交
    148     double p=point_to_line(b.p,a);
    149     if(dcmp(p-b.r)==0)    return 1;
    150     return (dcmp(p-b.r)<0? 2: 0);
    151 }
    152 
    153 Point tmp[410];
    154 int convex_hull(Point *p,int n,Point *ch){    //求凸包
    155     int m=0;
    156     sort(p,p+n);
    157     for(int i=0;i<n;i++){
    158         while(m>1&&dcmp(cross(tmp[m-1]-tmp[m-2],p[i]-tmp[m-1]))<=0)    m--;
    159         tmp[m++]=p[i];
    160     }
    161     int k=m;
    162     for(int i=n-2;i>=0;i--){
    163         while(m>k&&dcmp(cross(tmp[m-1]-tmp[m-2],p[i]-tmp[m-1]))<=0)    m--;
    164         tmp[m++]=p[i];
    165     }
    166     if(n>1)    m--;
    167     for(int i=0;i<m;i++)    ch[i]=tmp[i];
    168     return m;
    169 }
    170 
    171 int dp[410][410];
    172 Point point[410];
    173 Circle circle[120];
    174 bool rel[410][410];
    175 
    176 int main(void){
    177     int T;  scanf("%d",&T);
    178     while(T--){
    179         memset(dp,0,sizeof(dp));
    180         memset(rel,0,sizeof(rel));
    181         int n,m,ans=0;    double r;   scanf("%d%d%lf",&n,&m,&r);
    182         for(int i=0;i<n;i++)    point[i].input();
    183         for(int i=0;i<m;i++)    circle[i].p.input(),circle[i].r=r;
    184         n=convex_hull(point,n,point);
    185         for(int i=0;i<n;i++)
    186             for(int j=i+2;j<n-(i==0);j++){
    187                 int flag=1;
    188                 for(int z=0;z<m;z++)
    189                     if(relation(Line(point[i],point[j]),circle[z])){
    190                         flag=0;
    191                         break;
    192                     }
    193                 if(flag)    rel[i][j]=rel[j][i]=1;
    194             }
    195         for(int t=0;t<2*n;t++)
    196             for(int s=max(0,t-n+1);s<=t;s++)
    197                 for(int i=t;i>=s;i--)
    198                     dp[s][t]=max(dp[s][t],dp[s][i]+rel[s%n][t%n]);
    199         for(int i=n-1;i<2*n;i++)    ans=max(ans,dp[i-n+1][i]);
    200         printf("%d
    ",ans);
    201     }
    202     return 0;
    203 }
  • 相关阅读:
    OSI及TCP/IP的概念和区别
    http协议介绍
    Http协议之Content-Length
    粒子群优化算法
    十分钟理解Actor模式
    tomcat原理解析(二):整体架构
    tomcat原理解析(一):一个简单的实现
    【linux】CentOS安装mysql*.rpm提示conflicts with file from package的解决办法
    [分布式] 保证分布式系统数据一致性的6种方案
    【svn】 SVN错误:Attempted to lock an already-locked dir
  • 原文地址:https://www.cnblogs.com/dd-bond/p/11266354.html
Copyright © 2011-2022 走看看