WC2018 州區劃分(FWT,動態規劃)

2022-03-19 23:10:15 字數 1569 閱讀 9822

uoj

洛谷首先有乙個暴力做法(就有\(50\)分了)

先\(o(2^nn^2)\)預處理出每個子集是否合法,然後設\(f[s]\)表示當前的答案,每次列舉乙個子集進行轉移,得到方程:\(\displaystyle f[s]=(\frac)^p\sum_f[t]*(w_)^p*check[s-t]\)。

其中\(w\)表示權值和,\(check\)表示是否合法。

這樣子的複雜度是\(o(3^n)\),然後似乎可以拿\(50\)分了。

後面那個東西很像乙個卷積,然而直接\(or\)卷積的話,會算出很多我們不想要的東西。

聽說這個玩意叫做子集卷積。

要做的就是\(\sum f[t]*g[w]*[t\cup w=s,t\cap w=\phi]\)

可以用二進位制下\(1\)的個數來表示這個限制\(\sum f[t]*g[w]*[t\cup w=s,cnt(t)+cnt(w)=cnt(s)]\)。

其中\(cnt(s)\)表示\(s\)中\(1\)的個數。

然後聽說這個玩意就是乙個套路了。。。

把集合的\(1\)的個數強制作為一維狀態加上去。也就是\(f[cnt(s)][s]\)這樣子。

令\(g[cnt(s)][s]=(w_s)^p*check[s]\)。

這樣子的話只需要列舉兩者的\(1\)的個數就可以去掉位的限制,然後就只剩下兩者的交是\(s\)的限制,這個限制可以直接表示為或卷積(異或似乎也行???)。

那麼直接\(fwt\)按層處理即可。

#include#includeusing namespace std;

#define mod 998244353

#define max 25

void add(int &x,int y)

inline int read()

int fpow(int a,int b)

return s;

}int n,m,p,s,g[max],dg[max],lg[1<<21];

bool chk[1<<21];

int cc[1<<21];

int f[22][1<<21],g[22][1<<21],tmp[1<<21];

int w[max],w[1<<21],wk[1<<21],invw[1<<21];

void fwt(int *a,int opt)

chk[i]=false;int nw=0;

for(int j=0;jfor(int j=0;jfor(int j=0;jfor(int j=0;jif(cc[i]==1)chk[i]=false;

wk[i]=fpow(w[i],p);invw[i]=fpow(wk[i],mod-2);

if(chk[i])g[cc[i]][i]=wk[i];

} f[0][0]=1;fwt(f[0],1);

for(int i=1;i<=n;++i) /*

f[0]=1;

for(int i=1;if[i]=1ll*f[i]*invw[i]%mod;

}*/printf("%d\n",f[n][s-1]);

return 0;

}

WC2018 州區劃分

點此看題 設d p s dp s dp s 為選出來的點狀壓為s ss,所得到的滿意度總和,轉移 d p s 1 f s i s dp i g s i dp s frac sum dp i times g s i dp s f s 1 i s d p i g s i 其中f s f s f s 是w...

WC 2018 州區劃分

給乙個無向圖 g v,e 滿足 v 21 對於某一種將 g v,e 劃分為k個的有序集合方案,若每乙個子集 g i v i,e i e i 都不存在尤拉迴路,則會對答案貢獻為 其中,x 為集合元素,w x 為元素 x 的權值。題解 被題意坑成cu 我還是太菜了 其實很顯然我們會得到乙個 dp 設 f...

WC2018 州區劃分

題目 就當那個判斷乙個州不合法的條件是存在尤拉迴路吧 一張無向圖存在尤拉迴路的條件是 圖連通不存在度數為奇數的點 於是我們列舉每乙個子集,可以在 o 2 nn 2 的時間內判斷乙個集合是否能獨立成為乙個州 之後我們設 dp i 表示選取狀態為 i 的時候的答案,s i 為這個狀態對應的城市的人口之和...