zoukankan      html  css  js  c++  java
  • 洛谷 P2831 愤怒的小鸟

    洛谷:P2831 愤怒的小鸟

    题目传送门

    本题是一道很明显的状压DP,麻烦的是浮点数的处理和抛物线的计算,这里讲一些注意事项:

    一.浮点数判相等:

     

    二.抛物线的判断:

    题目中的抛物线有两个未知数,在正常情况下,每两点便可确定一条抛物线,但以下情况除外:

    1.两点所在的直线经过原点

    2.两点横坐标相等

    3.a < 0

    做法:

    1、N3预处理出所有抛物线,及其能经过的点。

    2、转移。

    其中还有许多优化,这里我用的是最暴力的方法。

    注:本题可用随机化。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    int para[650];
    int tot;
    #define inf 1000001
    int min(int x,int y)
    {
      return x<y?x:y;
    }
    double Mx(double x,double y)
    {
      return x>y?x:y;
    }
    double abs(double x)
    {
      return x>0?x:-x;
    }
    int dp[1<<19];
    double X[21],Y[21];
    #define eps 1e-9
    bool Be(double x,double y)
    {
      if(abs(x-y)<=eps*Mx(abs(x),abs(y)))
      return true;
      else
      return false;
       
    }int wuxian[600],jzw=0;
    void init()
    {
      for(int i=0;i<=18;i++) X[i]=Y[i]=0;
      for(int i=0;i<=(1<<19)-1;i++)
          dp[i]=inf;
          dp[0]=0;
            jzw=tot=0;
      for(int i=1;i<=400;i++)para[i] = 0;
    }
    double geta(double x1,double y1,double x2,double y2)
    {
      return (y1*x2-y2*x1)/(x1*x1*x2-x2*x2*x1);
    }
    double getb(double x1,double y1,double x2,double y2)
    {
      return (y1*x2*x2-y2*x1*x1)/(x1*x2*x2-x2*x1*x1);
    }
    double getk(double x1,double y1,double x2,double y2)
    {
      if(Be(x1,x2)) return inf;
      return (y1-y2)/(x1-x2);
    }
    bool delta(double x1,double y1,double x2,double y2)
    {
      if(x1==x2) return 0 ;
      double k=getk(x1,y1,x2,y2);
      double b=y1-k*x1;
      if(Be(b,0))
          return 1;
      if(Be(b,eps))
          return 1;
      return 0;
    }
    void build_dp(int n)
    {
      for(int i=0;i<n;i++)
      {
          double x1 = X[i+1];
          double y1 = Y[i+1];
          dp[1<<i] = 1;
        //   printf("%f %f",x1,y1);
          for(int j=0;j<n;j++)
          {
              double x2 = X[j+1];
              double y2 = Y[j+1];
              if(x1==x2) continue;
               
              double a = geta(x1,y1,x2,y2);
              double b = getb(x1,y1,x2,y2);
          //     printf("%f ",a);
              if(a>0 || delta(x1,y1,x2,y2)) continue ;
              dp[(1<<j)|(1<<i)] = 1;
              int sta=(1<<j)|(1<<i);
              for(int k=0;k<n;k++)
              {
                  double x3 = X[k+1];
                  double y3 = Y[k+1];
                  dp[1<<k] = 1;
                  double yy = a*x3*x3+b*x3;
                  if(Be(yy,y3))
                  {
                      sta|=1<<k;
                      dp[sta]=1;
                  }
              }
          }
      }
    }

    void build_para(int n)
    {
      for(int i=1;i<=(1<<n)-1;i++)
      {
          if(dp[i]==1) para[++tot] = i;
      }
    }
    int main()
    {
      int T;
      scanf("%d",&T);
      while(T--)
      {
          int n,m;
          scanf("%d%d",&n,&m);
          init();
          for(int i=1;i<=n;i++)
              scanf("%lf%lf",&X[i],&Y[i]);
          build_dp(n);
          build_para(n);
    // for(int i=1;i<=tot;i++) printf("%d ",para[i]);
    // for(int i=1;i<=tot;i++) printf("%d ",para[i]);  
          for(int i=1;i<=tot;i++)
          {
              int hit = para[i];
              for(int j=0;j<=(1<<n)-1;j++)
              dp[j|hit] = min(dp[j|hit],dp[j]+1);
          }
          printf("%d ",dp[(1<<(n))-1]);
      }
    }



  • 相关阅读:
    Please check logcat output for more details
    如何移植freertos
    依赖: nginx-common (= 1.14.0-0ubuntu1) 但是它将不会被安装
    错误:22 http://ppa.launchpad.net/fkrull/deadsnakes/ubuntu bionic Release 404 Not Found [IP: 91.189.95.83 80]
    由于没有公钥,无法验证下列签名:
    jQuery的TAB切换+定时器
    CSS问题1:div中 li宽度不固定 ie6和ie7不兼容不自动换行
    (转)Sqlite中INTEGER PRIMARY KEY AUTOINCREMENT和rowid的使用
    (转)JS加载顺序
    (转)在网页中JS函数自动执行常用三种方法
  • 原文地址:https://www.cnblogs.com/Marcelo/p/13806108.html
Copyright © 2011-2022 走看看