zoukankan      html  css  js  c++  java
  • 【LOJ2540】「PKUWC2018」随机算法

    题意

    题面

    给一个 (n) 个点 (m) 条边的无向图。考虑如下求独立集的随机算法:随机一个排列并按顺序加点。如果当前点能加入独立集就加入,否则不加入。求该算法能求出最大独立集的概率。

    (nle 20)

    Solution

    考虑状压DP。按照题意我们按顺序加点,如果该点不能加入独立集,那么这个点可以插在之后排列的某一个位置中。

    我们记当前排列独立集中的点的集合不在独立集中的点的个数为状态,设 (F(S,i)) 表示当前独立集点的集合为 (S),还有 (i) 个点没有插入排列。

    可以用高维前缀和预处理每个集合的相邻的点(包括集合本身的点。记为 (g(S))),这样就可以 (O(2^n imes n^2)) 的预处理每个点 (u) 当前集合加入独立集 (s) 后新的相邻的点,记为 (h(u,S))

    我们有

    [F(S,i-1) leftarrow F(S,i) imes i \ F(Scup u,i+h(u,S)) leftarrow F(S,i) (u otin g(S)) ]

    DP 的时间复杂度是 (O(2^n imes n^2))。可以通过本题。当然这不是本题的最优复杂度。

    code

    #include<bits/stdc++.h>
    #pragma GCC target("popcnt")
    using namespace std;
    const int N=21,Mod=998244353;
    int g[1<<N],f[1<<N][N],t[N],ans,mx,n,m;
    void upd(int& x, int y)
    {
    	x=(x+y>=Mod?x+y-Mod:x+y);
    }
    #define mul(x,y) (1ll*(x)*(y)%Mod)
    inline int po(int x, int y=Mod-2)
    {
    	int r=1;
    	while(y)
    	{
    		if(y&1) r=mul(r,x);
    		x=mul(x,x), y>>=1;
    	}
    	return r;
    }
    int main()
    {
    	scanf("%d%d",&n,&m);
    	for(int i=1,u,v;i<=m;++i)
    	{
    		scanf("%d%d",&u,&v),--u,--v;
    		g[1<<u]|=(1<<u)|(1<<v);
    		g[1<<v]|=(1<<u)|(1<<v);
    	}
    	for(int s=1;s<(1<<n);++s)
    		for(int i=0;i<n;++i) if(s&(1<<i)) g[s]|=g[s^(1<<i)];
    	f[0][0]=1;
    	for(int s=0;s<(1<<n);++s)
    	{
    		for(int i=n;i;--i) upd(f[s][i-1],mul(f[s][i],i));
    		memset(t,0,sizeof(t));
    		for(int x=0;x<n;++x) if(!(g[s]&(1<<x)))
    			t[x]=__builtin_popcount((g[1<<x]^(1<<x))&(~g[s]));
    		for(int i=0;i<=n;++i) if(f[s][i])
    			for(int x=0;x<n;++x) if(!(g[s]&(1<<x)))
    				upd(f[s|(1<<x)][i+t[x]],f[s][i]);
    	}
    	for(int s=0;s<(1<<n);++s)
    	{
    		const int cnt=__builtin_popcount(s);
    		if(cnt>mx&&f[s][0]) mx=cnt,ans=f[s][0];
    		else if(cnt==mx) upd(ans,f[s][0]);
    	}
    	int fac=1; for(int i=1;i<=n;++i) fac=mul(fac,i);
    	printf("%d",mul(ans,po(fac)));
    }
    
  • 相关阅读:
    HBase 操作
    HBase Java API 例子
    微信浏览器拖动出现黑色/白色背景、网址问题解决方案
    layui弹出层置顶弹出
    使用layui时,ajax执行后,重新渲染页面的方法
    宝塔更新
    js 播放音频文件 兼容火狐 谷歌浏览器
    SAP断点
    error_log 用法
    SE开头的事务代码
  • 原文地址:https://www.cnblogs.com/farway17/p/12007147.html
Copyright © 2011-2022 走看看