zoukankan      html  css  js  c++  java
  • [hdu contest 2019-07-29] Azshara's deep sea 计算几何 动态规划 区间dp 凸包 graham扫描法

    今天hdu的比赛的第一题,凸包+区间dp。

    给出n个点m个圆,n<400,m<100,要求找出凸包然后给凸包上的点连线,连线的两个点不能(在凸包上)相邻,连线不能与圆相交或相切,连线不能相交但是可以有公共端点。

    首先找出凸包,然后把n*n条边和m个圆算点到直线距离验证一下边是否与圆相交存到e[n][n]里。

    然后显然是一个dp,但是我开始看错题目了以为不能有公共端点,能有公共端点的情况考虑一下像一个找三角形的过程,就是区间dp。

    区间dp有一点妙的地方是最大区间范围是凸包点数而不用+1,因为连线的两个点不能在凸包上相邻所以这样就能直接得到最大值。

    今天疯狂坑队友了,我要是帮着队友查错就能多对一道题了,因为自己菜没有写出来题还连累队友真的真的很抱歉。

    代码在下面,也算是复习dp和码一个找凸包板子,这个方法好像叫graham扫描法?

     1 #include<iostream>
     2 #include<cmath>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<cstdlib>
     6 #include<string>
     7 #include<algorithm>
     8 #include<vector>
     9 #include<iomanip>
    10 #include<stack>
    11 #include<queue> 
    12 using namespace std;
    13 const int maxn=410;
    14 int n,m,cnt;
    15 int tot;
    16 double r;
    17 struct nod{
    18     double x,y;
    19 }poi[maxn],po[maxn*2],ci[maxn];
    20 bool e[maxn][maxn]={};
    21 int f[maxn*2][maxn*2]={};
    22 bool cmp(nod a,nod b){
    23     double aa=atan2(a.y-po[1].y,a.x-po[1].x);
    24     double bb=atan2(b.y-po[1].y,b.x-po[1].x);
    25     if(aa==bb) return a.x<b.x;
    26     return aa<bb;
    27 }
    28 double cro(nod a,nod b,nod c){
    29     return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);
    30 }
    31 void getpo(){
    32     int t=1;
    33     for( int i=2; i<=n; ++i) {
    34         if( poi[i].y < poi[t].y||( poi[i].y == poi[t].y&&poi[i].x < poi[t].x) ) t=i;
    35     }
    36     po[++cnt]=poi[t];swap(poi[t],poi[1]);
    37     sort(poi+2,poi+n+1,cmp);
    38     po[++cnt]=poi[2];
    39     for(int i=3;i<=n;++i){
    40         //cout<<poi[i].x<<poi[i].y<<endl;
    41         while(cnt>1&&cro(po[cnt-1],poi[i],po[cnt])>=0)--cnt;
    42         po[++cnt]=poi[i];
    43     }
    44 }
    45 int main(){
    46     int T;scanf("%d",&T);
    47     while(T--){
    48         tot=1;
    49         cnt=0;
    50         memset(e,0,sizeof(e));
    51         memset(f,0,sizeof(f));
    52         scanf("%d%d%lf",&n,&m,&r);
    53         for( int i=1; i<=n; ++i) scanf("%lf%lf",&poi[i].x,&poi[i].y);
    54         for( int i=1; i<=m; ++i) scanf("%lf%lf",&ci[i].x,&ci[i].y);
    55         getpo();//cout<<1111111<<endl;
    56         for(int i=1;i<=cnt;++i){
    57         //    cout<<po[i].x<<po[i].y<<endl;
    58             for(int j=i+2;j<=cnt;++j){
    59                 if(i==1&&j==cnt)continue;
    60                 double a=po[i].y-po[j].y,b=po[j].x-po[i].x;
    61                 double c=-(a*po[i].x+b*po[i].y);
    62                 e[i][j]=1;
    63                 e[j][i]=1;
    64                 for(int w=1;w<=m;++w){
    65                     double ju=a*ci[w].x+b*ci[w].y+c;
    66                     if(ju<0)ju=-ju;
    67                     ju/=sqrt(a*a+b*b);
    68                     if(ju>r)continue;
    69                     e[i][j]=0;
    70                     e[j][i]=0;
    71                 }
    72                     //cout<<i<<j<<e[i][j]<<endl;
    73             }
    74         }
    75         int ans=0;
    76         for(int k=1;k<=cnt;++k){
    77             for(int i=1,j=k;j<cnt*2;++i,++j){
    78                 for(int t=i;t<=j;++t){
    79                     f[i][j]=max(f[i][j],f[i][t]);
    80                     if(e[(t-1)%cnt+1][(j-1)%cnt+1])f[i][j]=max(f[i][j],f[i][t]+1);
    81                 }
    82             }
    83         }
    84         for(int i=1;i<=cnt;++i)ans=max(ans,f[i][i+cnt-1]);
    85         printf("%d
    ",ans);
    86     }
    87     return 0;
    88 }
    View Code
  • 相关阅读:
    shell的执行顺序问题
    七层负载均衡——HAProxy
    不要自以为是码农
    SSL协议运行机制
    Linux启动流程
    MIM协议与Base64编码
    Adele的生活
    你值得拥有:25个Linux性能监控工具
    [Zabbix] 如何实现邮件报警通知以及免费短信报警通知
    php.ini中date.timezone设置分析
  • 原文地址:https://www.cnblogs.com/137shoebills/p/11267278.html
Copyright © 2011-2022 走看看