zoukankan      html  css  js  c++  java
  • [PKUWC2018]随机算法

    Link

    Solution

    随便状压就可以了,设f[S]为答案,g[S]为S的最大独立集点数。对于每个S,枚举其点集内每个点作为p[1],那么选了这个点之后与其相连的所有点(记作r[i])都不能选,是个递归过程。
    转移有 (f_S=frac{sumlimits_{iin S}f_{S-r[i]}:: imes [g_{S-r[i]}:: +1==g_S]}{|S|})

    Code

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    inline int read(){//be careful for long long!
        register int x=0,f=1;register char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')f=0;ch=getchar();}
        while(isdigit(ch)){x=x*10+(ch^'0');ch=getchar();}
        return f?x:-x;
    }
    
    const int N=21,mod=998244353;
    int n,m,rel[N],f[1<<N],g[1<<N],inv[N];
    
    int main(){
        n=read(),m=read();inv[1]=1;
        for(int i=2;i<=n;++i)inv[i]=(mod-1ll*(mod/i)*inv[mod%i]%mod)%mod;
        for(int i=1;i<=m;++i){
    	int u=read(),v=read();
    	rel[u]|=(1<<(v-1)),rel[v]|=(1<<(u-1));
        }
        for(int i=1;i<=n;++i)rel[i]|=(1<<(i-1));
        f[0]=1;int all=(1<<n)-1;
        for(int s=1;s<=all;++s){
    	int cnt=0;
    	for(int i=1;i<=n;++i)
    	    if((s>>(i-1))&1){
    		++cnt;
    		int t=s&(all^rel[i]);
    		if(g[t]>=g[s])g[s]=g[t]+1,f[s]=f[t];
    		else if(g[t]==g[s]-1)f[s]=(f[s]+f[t])%mod;
    	    }
    	f[s]=1ll*f[s]*inv[cnt]%mod;
        }
        printf("%d
    ",f[all]);
        return 0;
    }
    
    
  • 相关阅读:
    《构建之法》第8、9、10章的读后感和第一个sprint总结
    实验三 进程调度模拟程序
    构建之法第6、7章的读后感
    实验二 作业调度模拟程序
    0415博客园评价
    0414复利计算6.0-----结对编程
    0408~送给小伙伴的汉堡包
    学习进度条
    Sprint three
    sprint one
  • 原文地址:https://www.cnblogs.com/fruitea/p/12023944.html
Copyright © 2011-2022 走看看