我們考慮用狀壓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 為最大獨立集。這種情況,相當於在原本的最大獨立...