zoukankan      html  css  js  c++  java
  • NOIp2016 愤怒的小鸟 【状压dp】By cellur925

    题目传送门

    注:本文中绿鸟==猪!

    这道题开始一看数据范围我们就知道是一道状压dp,因为绿鸟仅有18个,但是开始看(m)好像没太懂什么意思。既然确定了是状压,那就来设计状态,一般状压的状态肯定是要有二进制的串的,可能还会有其他,但是这个题好像没有别的参数需要记录,暂且设(0)为绿鸟没有被打,(1)表示绿鸟已经死亡,(f[i])表示状态为(i)时所需要的最少的鸟数来打诶我刚才在说什么绿鸟

    考虑转移,想转移的时候大概有一个模糊的概念:一个状态或((or))上另一个状态等于一个状态(+1)。但是又对题目中给出的抛物线产生了疑惑(怎么搞出来的),后来通过捡起放下很久的解析几何芝士想到好像这个抛物线仅有(a,b)两个参数且(a<=0),这样两点就能确定一条抛物线..之后的思路有点混乱,感觉无法把两者结合在一起,我还是太菜了==。

    一种想法是(O(T*2^n*n^2))的算法。我们先预处理出每根抛物线,求出每条抛物线打绿鸟对应的状态。然后转移的时候枚举每根抛物线就好。怎么处理抛物线?先两两枚举点,解出他们的抛物线,然后注意横坐标相同的两点不可解(因为差值为0,之后会整数被0除),最后再记录一下只有一个点在的抛物线。

    还有是要注意下精度问题:这是自己绝对想不到的。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define maxn 400090
    
    using namespace std;
    const double eps=1e-8;
    
    int T,n,m,tot,fake;
    int lin[maxn],f[maxn],vis[100];
    struct point{
        double x,y;
    }p[100];
    
    void calc(int i,int j)
    {
        double a=(p[j].x*p[i].y-p[j].y*p[i].x)/(p[i].x*p[j].x*(p[i].x-p[j].x));
        if(a>=0) return ;
        double b=p[j].y/p[j].x-a*p[j].x;
        tot++;
        for(int k=1;k<=n;k++)
        {
            double qwq=p[k].x*p[k].x*a+b*p[k].x;
            if(qwq-p[k].y>=eps||p[k].y-qwq>=eps) continue;
            lin[tot]|=(1<<(k-1));vis[k]=1;
        }
    }
    
    int main()
    {
        scanf("%d",&T);
        while(T--)
        {
            tot=0;
            memset(lin,0,sizeof(lin));
            memset(vis,0,sizeof(vis));
            scanf("%d%d",&n,&m);
            for(int i=1;i<=n;i++) scanf("%lf%lf",&p[i].x,&p[i].y);
            for(int i=1;i<=n;i++)
                for(int j=i+1;j<=n;j++)
                    if(p[i].x!=p[j].x) calc(i,j);
            for(int i=1;i<=n;i++)
                if(!vis[i]) lin[++tot]=(1<<(i-1));
            memset(f,0x3f,sizeof(f));
            f[0]=0;
            fake=(1<<n)-1;
            for(int i=0;i<=fake;i++)
                for(int j=1;j<=tot;j++)
                    f[i|lin[j]]=min(f[i|lin[j]],f[i]+1);
            printf("%d
    ",f[fake]);
        }
        return 0;
    }
    
  • 相关阅读:
    JS document.execCommand实现复制功能(带你出坑)
    jquery动态添加删除一行数据示例
    SpringBoot SpEL表达式注入漏洞-分析与复现
    Fastjson 1.2.22-24 反序列化漏洞分析
    udf提权原理详解
    ZZCMS v8.2 前台Insert注入+任意文件删除
    安恒杯 3月线上个人赛WriteUp
    SQLI LABS Stacked Part(38-53) WriteUp
    【转】Ubuntu16.04安装docker
    安装部署k8s-版本-1.13
  • 原文地址:https://www.cnblogs.com/nopartyfoucaodong/p/9874625.html
Copyright © 2011-2022 走看看