pkuwc2018 隨機演算法

2022-09-22 00:30:11 字數 1383 閱讀 1286

我們考慮用狀壓dp來解決這一道題

設$f[i][s]$表示當前排列的前i位所構成的最大獨立集恰好為s的方案數

我們考慮用$f[i][s]$推出$f[i+1][s']$的值

那麼我們有兩種擴充套件的方法,一種是在第$i+1$位,加入乙個數$j$,滿足$s∩j=∅$,且$s∪j$為最大獨立集。

這種情況,相當於在原本的最大獨立集中,新加入了乙個點j,那麼顯然可以對答案產生貢獻

則有$f[i+1][s|(1<

另一種是:我們在第i+1位,填入乙個不會對最大獨立集產生變化的數。

根據題意,我們要填入乙個數j,滿足集合s中,存在於節點$j$相鄰的點。

則有$f[i+1][s]+=f[i][s]*(p[s]-i) $,其中$p[s]$表示與集合$s$相連的點的個數+集合$s$所包含的點數

設題目中所給的圖的最大獨立集大小為$k$

最後的答案顯然為$\dfracf[n][k]}$

#include#define m 20

#define lowbit(x) ((x)&(-(x)))

#define mod 998244353

#define l long long

using

namespace

std;

l pow_mod(l x,l k)

int a[m],ok[1

<1

<1

intmain()

ok[0]=1

;

for(int i=0;i)

if(ok[i])

int maxn=0;//

最大獨立集大小

for(int i=1;iif(ok[i]) maxn=max(maxn,siz[i]);

for(int i=1;i)

for(int j=0;j)

if(i&a[j]) p[i]++;

//p[s] 與點集s相連的點數為多少(包括s中的點)

f[0][0]=1

;

for(int i=0;i)

for(int s=0;s)

if(f[i][s])

}l ans=0

;

for(int s=1;s)

if(siz[s]==maxn&&ok[s]==1

) ans=(ans+f[n][s])%mod;

l fac=1

;

for(int i=1;i<=n;i++) fac=fac*i%mod;

printf(

"%lld\n

",ans*pow_mod(fac,mod-2)%mod);

}

PKUWC2018 隨機演算法

題意 給定乙個圖 n 20 定義乙個求最大獨立集的隨機化演算法 產生乙個排列,依次加入,能加入就加入 求得到最大獨立集的概率 本質就是計數題 每個點有三種狀態 考慮過且在獨立集中,考慮過未在獨立集中,未考慮 本來在集合裡的點不能知道有哪些,而且不能加入的點的排列也不好確定。乙個好的方法是 把考慮過的...

PKUWC2018 隨機演算法

題目 思博狀壓寫不出是不是沒救了呀 首先我們直接狀壓當前最大獨立集的大小顯然是不對的,因為我們的答案還和我們考慮的順序有關 我們發現最大獨立集的個數好像不是很多,可能是 o n 級別的,於是我們考慮從這個方面入手 我們求出所有的最大獨立集,考慮求出有多少種考慮順序能夠恰好得到這個最大獨立集 設當前已...

pkuwc2018 隨機演算法

我們考慮用狀壓dp來解決這一道題 設 f i s 表示當前排列的前i位所構成的最大獨立集恰好為s的方案數 我們考慮用 f i s 推出 f i 1 s 的值 那麼我們有兩種擴充套件的方法,一種是在第 i 1 位,加入乙個數 j 滿足 s j 且 s j 為最大獨立集。這種情況,相當於在原本的最大獨立...