• bzoj1076 [SCOI2008]奖励关


    bzoj1076 [SCOI2008]奖励关


    特别水的一道dp。
    n<=15那肯定状压
    枚举出现的宝物,判断选或不选
    复杂度(O(n^{2} imes2^n imes k))

    mdzz可恶的latex..

    // It is made by XZZ
    #include<cstdio>
    #include<algorithm>
    #define Fname "2473"
    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
    #define db long double
    typedef long long ll;
    il int gi(){
        rg int x=0;rg bool flg=0;rg char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')flg=1;ch=getchar();}
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return flg?-x:x;
    }
    db f[101][1<<15];
    int p[16],lim,n,m;
    bool e[16][16];//e[i][j]表示有j才能捡i
    //f[i][j] i~n关 1~i-1宝物情况为j i~n的最大得分期望
    int main(){
    #ifdef xzz
        freopen(Fname".in","r",stdin);
        freopen(Fname".out","w",stdout);
    #endif
        n=gi(),m=gi(),lim=(1<<m)-1;
        rep(i,1,m){
            p[i]=gi();
            static int ls;while(ls=gi(),ls)e[i][ls]=1;
        }
        db eps=1.00/m,ls;
        bool flg;
        rep(i,0,lim)f[n+1][i]=0;
        drep(i,n,1)rep(j,0,lim){
            f[i][j]=0;
            rep(k,1,m){//第i轮丢的宝物为k
                ls=f[i+1][j];//不捡
                flg=1;
                rep(l,1,m)if(e[k][l]&&(j&(1<<l-1))==0){flg=0;break;}
                if(flg)ls=max(ls,f[i+1][j|(1<<k-1)]+p[k]);
                f[i][j]+=ls*eps;
            }
        }
        printf("%.6Lf
    ",f[1][0]);
        return 0;
    }
    

    一个较强的优化:预处理出某个状态时是否能放,省去每次判断的过程
    复杂度(O(n imes k imes2^n))

    // It is made by XZZ
    #include<cstdio>
    #include<algorithm>
    #define Fname "2473"
    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
    #define db long double
    typedef long long ll;
    il int gi(){
        rg int x=0;rg bool flg=0;rg char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')flg=1;ch=getchar();}
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return flg?-x:x;
    }
    db f[101][1<<15];
    int p[16],lim,n,m;
    bool e[16][16];
    bool yes[1<<15][16];
    int main(){
    #ifdef xzz
        freopen(Fname".in","r",stdin);
        freopen(Fname".out","w",stdout);
    #endif
        n=gi(),m=gi(),lim=(1<<m)-1;
        rep(i,1,m){
            p[i]=gi();
            static int ls;while(ls=gi(),ls)e[i][ls]=1;
        }
        rep(i,0,lim)rep(j,1,m){
            yes[i][j]=1;
            rep(k,1,m)if(e[j][k]&&(i&(1<<k-1))==0){yes[i][j]=0;break;}
        }
        rg db ls;
        drep(i,n,1)rep(j,0,lim){
            f[i][j]=0;
            rep(k,1,m){
                ls=f[i+1][j];
                if(yes[j][k])ls=max(ls,f[i+1][j|(1<<k-1)]+p[k]);
                f[i][j]+=ls;
            }f[i][j]/=m;
        }
        printf("%.6Lf
    ",f[1][0]);
        return 0;
    }
    

    更神奇的玄学优化:位运算改用数组初始化(OTZ IOT)

    // It is made by XZZ
    #include<cstdio>
    #include<algorithm>
    #define Fname "2473"
    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
    #define db double
    typedef long long ll;
    il int gi(){
        rg int x=0;rg bool flg=0;rg char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')flg=1;ch=getchar();}
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return flg?-x:x;
    }
    const int w[]={1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768};
    db f[101][1<<15];
    int p[16],lim,n,m;
    bool e[16][16];
    bool yes[1<<15][16];
    int main(){
    #ifdef xzz
        freopen(Fname".in","r",stdin);
        freopen(Fname".out","w",stdout);
    #endif
        n=gi(),m=gi(),lim=(1<<m)-1;
        rep(i,1,m){
            p[i]=gi();
            static int ls;while(ls=gi(),ls)e[i][ls]=1;
        }
        rep(i,0,lim)rep(j,1,m){
            yes[i][j]=1;
            rep(k,1,m)if(e[j][k]&&(i&w[k-1])==0){yes[i][j]=0;break;}
        }
        rg db ls;
        drep(i,n,1)rep(j,0,lim){
            f[i][j]=0;
            rep(k,1,m){
                ls=f[i+1][j];
                if(yes[j][k])ls=max(ls,f[i+1][j|w[k-1]]+p[k]);
                f[i][j]+=ls;
            }f[i][j]/=m;
        }
        printf("%.6lf
    ",f[1][0]);
        return 0;
    }
    
  • 相关阅读:
    gethostbyname() 用域名或主机名获取IP地址
    recv, recvfrom, recvmsg 从套接口接收一个消息
    献给初学者:谈谈如何学习Linux操作系统
    Linux 文件处理 之扫描目录 DIR
    Python 使用sys模块
    struct dirent和DIR结构体
    职场人必读的文字只花10分钟影响你一辈子!
    信号量与线程互斥锁的区别
    send/sendto/sendmsg函数解析
    互联网常见Open API文档资源
  • 原文地址:https://www.cnblogs.com/xzz_233/p/bzoj1076.html
Copyright © 2020-2023  润新知