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

    洛谷P2831 愤怒的小鸟

    原题链接

    题解

    首先简单数学公式送上。
    (ax_1^2+bx_1=y_1)
    (ax_2^2+bx_2=y_2)
    (ax_1^2x_2+bx_1x_2=y_1x_2)
    (ax_2^2x_1+bx_2x_1=y_2x_1)
    (a=(y_1x_2-y_2x_1)/x_1x_2(x_1-x_2))
    (b=(y_1-ax_1^2)/x_1)
    不用证明吧。。。

    85分

    状态压缩。每次枚举两个点计算抛物线,然后消除这条线上所有点,再转移。

    // It is made by XZZ
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    #define rep(a,b,c) for(rg int a=b;a<=c;a++)
    #define drep(a,b,c) for(rg int a=b;a>=c;a--)
    #define erep(a,b) for(rg int a=fir[b];a;a=nxt[a])
    #define il inline
    #define rg register
    #define vd void
    typedef long long ll;
    il int gi(){
        rg int x=0,f=1;rg char ch=getchar();
        while(ch<'0'||ch>'9')f=ch=='-'?-1:f,ch=getchar();
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return x*f;
    }
    #define db double
    db x[18],y[18],eps=0.00000001;
    int f[1<<18],n;
    il int dp(int v){
        if(v==0)return 0;
        if(v==(v&-v))return 1;
        if(f[v])return f[v];
        f[v]=233;
        rep(i,0,n-1)if(v&(1<<i))rep(j,i+1,n-1)if((v&(1<<j))){
            db a=(y[i]*x[j]-y[j]*x[i])/(x[i]*x[j]*(x[i]-x[j])),b=(y[i]-a*x[i]*x[i])/(x[i]);
            if(a>=0)continue;
            int V=v;
            rep(k,0,n-1)if((V&(1<<k))&&fabs(a*x[k]*x[k]+b*x[k]-y[k])<=eps)V^=1<<k;
            f[v]=min(f[v],dp(V)+1);
        }
        rep(i,0,n-1)if(v&(1<<i))f[v]=min(f[v],dp(v^(1<<i))+1);
        return f[v];
    }
    il vd work(){
        n=gi();gi();
        rep(i,0,n-1)scanf("%lf%lf",&x[i],&y[i]);
        rep(i,0,(1<<n)-1)f[i]=0;
        printf("%d
    ",dp((1<<n)-1));
    }
    int main(){
        int T=gi();
        while(T--)work();
        return 0;
    }
    

    AC算法

    上面理论复杂度(O(2^nn^2T))。会炸。
    思考原因。
    显然算重情况较多。
    再想想。。。每个状态的第一头猪最后肯定要被打死(废话)。强制它第一个死,只需枚举一个点
    理论复杂度(O(2^nnT))

    // It is made by XZZ
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    #define rep(a,b,c) for(rg int a=b;a<=c;a++)
    #define drep(a,b,c) for(rg int a=b;a>=c;a--)
    #define erep(a,b) for(rg int a=fir[b];a;a=nxt[a])
    #define il inline
    #define rg register
    #define vd void
    typedef long long ll;
    il int gi(){
        rg int x=0,f=1;rg char ch=getchar();
        while(ch<'0'||ch>'9')f=ch=='-'?-1:f,ch=getchar();
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return x*f;
    }
    #define db double
    db x[18],y[18],eps=0.0000001;
    int f[1<<18],n;
    il int dp(int v){
        if(v==0)return 0;
        if(v==(v&-v))return 1;
        if(f[v])return f[v];
        f[v]=233;
        int j=log2(v&-v);
        rep(i,j+1,n-1)if(v&(1<<i)){
            db a=(y[i]*x[j]-y[j]*x[i])/(x[i]*x[j]*(x[i]-x[j])),b=(y[i]-a*x[i]*x[i])/(x[i]);
            if(a>=0)continue;
            int V=v;
            rep(k,j,n-1)if((V&(1<<k))&&fabs(a*x[k]*x[k]+b*x[k]-y[k])<=eps)V^=1<<k;
            f[v]=min(f[v],dp(V)+1);
        }
        f[v]=min(f[v],dp(v-(v&-v))+1);
        return f[v];
    }
    il vd work(){
        n=gi();gi();
        rep(i,0,n-1)scanf("%lf%lf",&x[i],&y[i]);
        rep(i,0,(1<<n)-1)f[i]=0;
        printf("%d
    ",dp((1<<n)-1));
    }
    int main(){
        int T=gi();
        while(T--)work();
        return 0;
    }
    
  • 相关阅读:
    Windows下图文详解PHP三种运行方式(php_mod、cgi、fastcgi)
    【强烈推荐】利用NAT、Host-Only双虚拟网卡,实现Virtual Box中CentOS6.3联网
    PHP批量清空删除指定文件夹内容
    MySQL收藏
    Eclipse快捷键与使用技巧总结
    “知乎网”技术方案初探
    PHP数组常用函数
    PHP常用字符串的操作函数
    Linux下,如何给PHP安装pdo_mysql扩展
    PHP二维数组排序(list_order)
  • 原文地址:https://www.cnblogs.com/xzz_233/p/7401327.html
Copyright © 2011-2022 走看看