zoukankan      html  css  js  c++  java
  • 【UOJ#422】【集训队作业2018】小Z的礼物(min-max容斥,轮廓线dp)

    【UOJ#422】【集训队作业2018】小Z的礼物(min-max容斥,轮廓线dp)

    题面

    UOJ

    题解

    毒瘤xzy,怎么能搬这种题当做WC模拟题QwQ
    一开始开错题了,根本就不会做。
    后来发现是每次任意覆盖相邻的两个,那么很明显就可以套(min-max)容斥。
    要求的就是(max(All)),而每个集合的(min)是很好求的。
    如果直接暴力枚举集合复杂度就是(2^{cnt}cnt)
    仔细想想每个子集我们要知道的是什么,只需要知道子集大小来确定前面的容斥系数,还需要知道覆盖子集的方案数,这样就可以知道(min)的概率,倒数就是期望了。
    而覆盖子集的方案数不会超过(2*n*m-n-m),显然要比(2^{cnt})优秀。
    所以枚举覆盖子集的方案数来(dp),至于子集大小之和容斥系数相关,而容斥系数只有正负(1),所以直接乘进去一起转移就好了,不需要单独存一维状态。
    考虑每次新加入一个点之后的覆盖方案,只需要知道当前位置四周是否已经存在于子集当中,那么直接状压当前的轮廓线就好了。
    设状态(f[S][k])表示覆盖方案数为(k),轮廓线为(S)时的方案数,容斥系数已经考虑进去。
    显然当前位置可以不选,那么直接转移。
    如果当前位置可以选入子集,那么乘上系数(-1),同时修改覆盖方案数以及轮廓线的状态转移。
    最后按照(min-max)容斥统计答案即可。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    #define MOD 998244353
    void add(int &x,int y){x+=y;if(x>=MOD)x-=MOD;}
    char g[200][200];
    int n,m,inv[1500],sum,pw,nw,ans,S;
    int f[2][1<<6][1200];
    int main()
    {
    	scanf("%d%d",&n,&m);S=1<<n;sum=2*n*m-n-m;
    	for(int i=1;i<=n;++i)scanf("%s",g[i]+1);
    	inv[0]=inv[1]=1;for(int i=2;i<1500;++i)inv[i]=1ll*inv[MOD%i]*(MOD-MOD/i)%MOD;
    	f[0][0][0]=MOD-1;
    	for(int i=1;i<=m;++i)
    		for(int j=1;j<=n;++j)
    		{
    			pw=nw;nw^=1;memset(f[nw],0,sizeof(f[nw]));
    			for(int T=0;T<S;++T)
    				for(int k=0;k<=sum;++k)
    					if(f[pw][T][k])
    					{
    						int nT=T&((S-1)^(1<<(j-1)));
    						add(f[nw][nT][k],f[pw][T][k]);
    						if(g[j][i]=='*')
    						{
    							nT|=1<<(j-1);int pls=0;
    							if(j>1&&!(T&(1<<(j-2))))++pls;
    							if(i>1&&!(T&(1<<(j-1))))++pls;
    							if(i<m)++pls;if(j<n)++pls;
    							add(f[nw][nT][k+pls],MOD-f[pw][T][k]);
    						}
    					}
    		}
    	for(int T=0;T<S;++T)
    		for(int i=1;i<=sum;++i)
    			add(ans,1ll*f[nw][T][i]*inv[i]%MOD);
    	ans=1ll*ans*sum%MOD;printf("%d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    Palindrome Partitioning
    Minimum Path Sum
    Maximum Depth of Binary Tree
    Minimum Depth of Binary Tree
    Unique Binary Search Trees II
    Unique Binary Search Trees
    Merge Intervals
    Merge Sorted Array
    Unique Paths II
    C++ Primer Plus 笔记第九章
  • 原文地址:https://www.cnblogs.com/cjyyb/p/10216412.html
Copyright © 2011-2022 走看看