• 【NOIP2016提高组】 Day2 T3 愤怒的小鸟


    题目传送门:https://www.luogu.org/problemnew/show/P2831

    说个题外话:NOIP2014也有一道题叫做愤怒的小鸟。

    这题自测时算错了eps,导致被卡了精度,从100卡剩80

    由于此题n的范围特别小,所以考虑使用状压dp。

    我们用一个整数i来描述状态,i的第k个bit表示第k只鸟是否被消灭,f[i]表示在这一状态下所需鸟的最小数量。

    由于不在同一直线上的三个点确定一条抛物线,所以我们可以预处理出所有的可行抛物线,并确定在该抛物线上的鸟的编号(这一步对精度要求极高)。同时考虑到两只鸟与原点存在三点共线的情况,故在抛物线方案中写入单独消灭指定一只小鸟的情况。故消灭方案之多有(n*(n-1)/2+n)种。

    然后就愉快地进行转移啦~ 顺便吐槽下m没有卵用

    时间复杂度为O(n^2*2^n)。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cmath>
     5 #define M 18
     6 #define eps (1e-10)
     7 using namespace std;
     8 int f[1<<M]={0};
     9 int n;
    10 struct pt{
    11     int x,y; pt(){x=y=0;}
    12     pt(double xx,double yy){x=xx; y=yy;}
    13 }a[M];
    14 struct pao{
    15     double a,b; pao(){a=b=0;}
    16     pao(pt A,pt B){
    17         double x0=A.x,x1=B.x,y0=A.y,y1=B.y;
    18         a=(y1-y0*x1/x0)/(x1*x1-x0*x1);
    19         b=y0/x0-a*x0;
    20     }
    21     bool check(){
    22         if(a>-eps) return 0;
    23         return 1;
    24     }
    25     double get(double x){
    26         double ans=a*x*x+b*x;
    27         return ans;
    28     }
    29 };
    30 int fly[M*M]={0},use=0;
    31 bool b[1<<M]={0};
    32 int Main(){
    33     memset(f,1,sizeof(f));
    34     memset(a,0,sizeof(a));
    35     memset(fly,0,sizeof(fly));
    36     memset(b,0,sizeof(b));
    37     use=0; int m;
    38     scanf("%d%d",&n,&m);
    39     for(int i=1;i<=n;i++){
    40         double x,y; scanf("%lf%lf",&x,&y);
    41         x=x*100+0.3; y=y*100+0.3;
    42         a[i]=pt(x,y);
    43     }
    44     for(int i=0;i<n;i++) fly[++use]=1<<i;
    45     for(int i=1;i<=n;i++){
    46         for(int j=1;j<i;j++) if(i!=j){
    47             if(a[i].x==a[j].x) continue;
    48             pao A=pao(a[i],a[j]);
    49             if(!A.check()) continue;
    50             int x=0;
    51             for(int k=0;k<n;k++){
    52                 double p=A.get(a[k+1].x);
    53                 if(fabs(p-a[k+1].y)<=eps)
    54                 x=x|(1<<k);
    55             }
    56             if(!b[x])
    57             fly[++use]=x,b[x]=1;
    58         }
    59     }
    60     int end=1<<n; f[0]=0;
    61     for(int i=0;i<end;i++){
    62         for(int j=1;j<=use;j++) 
    63         f[i|fly[j]]=min(f[i|fly[j]],f[i]+1);
    64     }
    65     printf("%d
    ",f[end-1]);
    66 }
    67 
    68 int main(){
    69     freopen("angrybirds.in","r",stdin);
    70     freopen("angrybirds.out","w",stdout);
    71     int cas; scanf("%d",&cas);
    72     while(cas--) Main();
    73     return 0;
    74 }
  • 相关阅读:
    C# GridView点击某列打开新浏览器窗口
    大白话系列之C#委托与事件讲解(二)
    大白话系列之C#委托与事件讲解(一)
    Razor语法大全
    Expression<Func<T,TResult>>和Func<T,TResult>
    C#委托的介绍(delegate、Action、Func、predicate)
    Android--样式经验
    Android--onSaveInstanceState()保存数据
    Android--ActivityLiving生命周期
    android--快捷键
  • 原文地址:https://www.cnblogs.com/xiefengze1/p/7725532.html
Copyright © 2020-2023  润新知