• 洛谷 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]);
      }
    }



  • 相关阅读:
    sql server 查询当前月份日期列表数据
    redis + cookies 实现持久登入
    JS浏览器兼容问题
    Multicast注册中心
    django模板高级进阶
    django高级视图和URL配置
    django表单操作之django.forms
    django站点管理
    django表单
    django数据库模型
  • 原文地址:https://www.cnblogs.com/Marcelo/p/13806108.html
Copyright © 2020-2023  润新知