zoukankan      html  css  js  c++  java
  • UOJ422 【集训队作业2018】小Z的礼物

    Description

    小Z有一个神奇的自动售货机,里面有$n imes m$种物品,分别放在$n$行$m$列个格子中。每当小Z向自动售货机中投入一枚硬币,他就能获得一对相邻格子中的物品(已经获得的物品可能再次获得),获得每一对相邻格子中的物品的概率是相等的。在这$n imes m$种物品中,有一些物品是小Z喜欢的(小Z喜欢的用 * [星号] 表示,其他的用 .[英文句号] 表示),他想把这些物品包装成一份礼物。小Z想知道,期望投入多少枚硬币后,就可以获得这些他喜欢的物品。

    Solution

    在一个$n imes m$的网格中随机选取一个$1 imes 2$的区域染色,求将给定的点全部染色的期望染色次数

    先Min-Max容斥一下,就变成了要求对于每个点集任意覆盖一个点的期望次数

    可算出$E(T)=frac{2mn-m-n}{x}$,$x$为点集中点的个数

    但是点集的数量大的飞起,所以设$dp_{i,j,s,cnt}$为考虑到格子$(i,j)$,轮廓线左侧的$n$个格子的选取情况为$s$,$x$值为$cnt$的所有点集的容斥系数之和

    每个染色区域在扫到其上方/左方格子时就记一次数,每个格子分不染色和染色两种情况讨论

    挺毒的

    #pragma GCC optimize(2)
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    long long n,m,dp[2][70][1205],inv[1205],sum,pre,cur=1,ans;
    const long long mod=998244353;
    char map[10][105];
    inline long long read()
    {
        long long w=0,f=1;
        char ch=0;
        while(ch<'0'||ch>'9')
        {
            if(ch=='-')
                f=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')
        {
            w=(w<<1)+(w<<3)+ch-'0';
            ch=getchar();
        }
        return w*f;
    }
    int main()
    {
        n=read();
        m=read();
        sum=2*n*m-n-m;
        inv[0]=inv[1]=1;
        for(long long i=2;i<=sum;i++)
        {
            inv[i]=inv[mod%i]*(mod-mod/i)%mod;
        }
        for(long long i=1;i<=n;i++)
        {
            scanf("%s",map[i]+1);
        }
        dp[cur][0][0]=mod-1;
        for(long long i=1;i<=m;i++)
        {
            for(long long j=1;j<=n;j++)
            {
                swap(cur,pre);
                memset(dp[cur],0,sizeof(dp[cur]));
                for(long long k=0;k<(1<<n);k++)
                {
                    for(long long l=0;l<=sum;l++)
                    {
                        long long now=k&(((1<<n)-1)^(1<<(j-1)));
                        (dp[cur][now][l]+=dp[pre][k][l])%=mod;
                        if(map[j][i]=='*')
                        {
                            now|=1<<(j-1);
                            long long cnt=0;
                            if(i>1&&!((1<<(j-1))&k))
                            {
                                ++cnt;
                            }
                            if(j>1&&!((1<<(j-2))&k))
                            {
                                ++cnt;
                            }
                            if(i<m)
                            {
                                ++cnt;
                            }
                            if(j<n)
                            {
                                ++cnt;
                            }
                            (dp[cur][now][l+cnt]+=mod-dp[pre][k][l])%=mod;
                        }
                    }
                }
            }
        }
        for(long long i=0;i<(1<<n);i++)
        {
            for(long long j=1;j<=sum;j++)
            {
                (ans+=dp[cur][i][j]*inv[j])%=mod;
            }
        }
        printf("%lld
    ",ans*sum%mod);
        return 0;
    }
    小Z的礼物
  • 相关阅读:
    css笔记
    微信小程序布局基础
    selenium打开ie,Firefox,chrome浏览器
    20170818,new的永远是个类,不是方法
    Java多线程的创建和运行
    二叉树的创建和遍历
    Java泛型用于方法,类和接口
    hadoop大作业
    hive基本操作与应用
    理解MapReduce计算构架
  • 原文地址:https://www.cnblogs.com/JDFZ-ZZ/p/13460962.html
Copyright © 2011-2022 走看看