SOS Dynamic Programming
·392 words·2 mins
๐ ์์ธ ์ ๋ฆฌ # $2^N$๊ฐ์ ์ ์ ๋ฐฐ์ด $A$๊ฐ ์ฃผ์ด์ง๋ค. ์ด๋ $\forall x$ ์ ๋ํด $F(x)$๋ฅผ $\sum\limits_{i \subseteq x}{A[i]}$ ๋ผ๊ณ ์ ์ํ์. ์ด๋ $x\&i = i$ ์ธ $i$๋ค์ ๋ํด $A[i]$์ ํฉ์ ์๋ฏธํ๋ค. ์์ ๊ฐ์ ๋ฌธ์ ๋ฅผ ์ด๋ป๊ฒ ํ ์์์๊น? ๋ธ๋ฃจํธํฌ์ค # ๋๋ฆฌ์ง๋ง, ๋ค์๊ณผ ๊ฐ์ ๋ธ๋ฃจํธํฌ์ค๋ก ๊ณ์ฐํ ์ ์๊ฒ ๋ค. for(int mask = 0; mask < (1<<N); mask++){ for(int i = 0; i < (1<<N); i++){ if((mask&i) == i){ F[mask] += A[i]; } } } ์ ์์ ๊ทธ๋๋ก ์ฎ๊ธด ๊ฒ์ ๊ฐ๊น๋ค. ์๊ฐ๋ณต์ก๋๋ ${(2^N)}^2 = 4^N$์ด๋ค. ์กฐ๊ธ ๋ ๋์ ํ์ด # ๋๋ฒ์งธ ๋ฐ๋ณต๋ฌธ์ ๋ํด, ๋ฐ๊นฅ์ชฝ ๋ฐ๋ณต๋ฌธ์์ ์ผ์ง์ง ์์ ๋นํธ์ ๋ํด์๋ ๋ฐ๋ณต์ ๋๋๊ฒ์ ๋๋ฌด ์๊น๋ค. ๋ฐ๋ผ์ ๋ค์๊ณผ ๊ฐ์ด๋ ํ๋ฒ ์๋ํด๋ณผ ์ ์๊ฒ ๋ค. for(int mask = 0; mask < (1<<N); mask++){ F[mask] = A[0]; for(int i = 0; i < (1<<N); i = (i-1)&mask) F[mask] += A[i]; } ์๊ฐ๋ณต์ก๋ ์ฆ๋ช
์ด ์ด๋ ค์๋ณด์ธ๋ค. ์ด๋ $\sum\limits_{k = 0}^N{\binom{N}{K}2^K} = 3^N$ ์ด๋ผ๊ณ ํ๋ค. Sum over Subsets DP # ์์ ๋ฐฉ์์์ ๋ณ๋ชฉ์ ์ด๋์์ ๋ํ๋ ๊น? ์ด๋ค $x$์ ๋นํธ๊ฐ $K$๊ฐ๊ฐ ๊บผ์ ธ์์ ๋, $A[x]$๋ $2^K$๊ฐ์ ๋ง์คํฌ์ ์ํด ๋ฐฉ๋ฌธ๋๋ค. ์ด ๋ฐ๋ณต์ ์ธ ์ฌ๊ณ์ฐ์ ์ค์ฌ์ผํ๋ค. S(mask, i) ์ ์ # ์ ๋ณ๋ชฉ์ ํผํ๊ธฐ ์ํด ์๋ก์ด ์ํ๋ฅผ ํ๋ ์ ์ํด๋ณด์. $S(mask, i)$๋ $mask$์ ๋ถ๋ถ์งํฉ๋ค ์ค, $mask$์ ํ์(์ค๋ฅธ์ชฝ) $i$๊ฐ ๋นํธ(0~i-1๋ฒ ์ธ๋ฑ์ค)์์๋ง ๋ค๋ฅธ ๊ฒ์ ์๋ฏธํ๋ค. ์๋ฅผ ๋ค์ด, $S(110, 2) = \{100, 110\}$์ด๋ค. ์ค๋ฅธ์ชฝ ๋๊ฐ ๋นํธ์์ ๋ค๋ฅผ ์ ์๋๋ฐ, ๋ถ๋ถ์งํฉ์ด์ด์ผ ํ๋ฏ๋ก $111$๊ฐ์๊ฑด ์๋๋ค. ์ด ์ ์๋ฅผ ์ด์ฉํ๋ฉด, ์ด๋ค ์งํฉ๋ ์๋ก ๊ฒน์น์ง ์๋ $S(mask, i)$๋ค์ ํฉ์งํฉ์ผ๋ก ๋ํ๋ผ ์ ์๊ฒ ๋๋ค. ์ ํ์ ์ ๋ # ์ ํ์์ ๋ค์๊ณผ ๊ฐ์ด ๋๊ฐ์ง๋ก ์ ์ํ ์ ์๊ฒ ๋ค. $mask$์ $i$๋ฒ์งธ ๋นํธ๊ฐ $0$์ธ ๊ฒฝ์ฐ $mask$์ ๋ถ๋ถ์งํฉ์ด $i$๋ฒ์งธ ๋นํธ์์ $0$๋ง์ ๊ฐ์ง ์ ์์ผ๋ฏ๋ก $S(mask, i) = S(mask, i-1)$ $mask$์ $i$๋ฒ์งธ ๋นํธ๊ฐ $1$์ธ ๊ฒฝ์ฐ $mask$์ ๋ถ๋ถ์งํฉ์ด $i$๋ฒ์งธ ๋นํธ์์ $0, 1$ ๋ชจ๋ ๊ฐ์ง ์ ์์ผ๋ฏ๋ก $S(mask, i) = S(mask, i-1) \cup S(mask \oplus 2^i, i-1)$ ๋ฐ๋ผ์ ์ด๋ฅผ ์ฝ๋๋ก ๋ํ๋ด๋ฉด ๋ค์๊ณผ ๊ฐ๋ค. for(int mask = 0; mask < (1<<N); mask++) DP[mask] = A[mask]; for(int i = 0; i<N; i++){ for(int mask = 0; mask < (1<<N); mask++){ if(mask & (1<<i)) DP[mask] += DP[mask ^ (1<<i)]; } } ๊ณ์ฐ ๊ฒฐ๊ณผ DP์ ๋ค์ด์๋ ๊ฐ์ ํด๋น ๋นํธ๋ง์คํน์ ๋ถ๋ถ์งํฉ์ ํฉ์ด๋ค. ์๊ฐ๋ณต์ก๋๋ ๊ทธ๋๋ก ๋ณด์ด๋ฏ์ด $O(N2^N)$์ด๋ค. N์ฐจ์ ๋์ ํฉ # https://blog.queuedlab.com/posts/sos-dp ๋ฅผ ์ฐธ๊ณ ํ๋ฉด, ์ด๋ฅผ $N$์ฐจ์ ๋์ ํฉ์ผ๋ก๋ ํด์ํ ์ ์๋ค. ํ์ดํผ ์์ด๊ณผ ํ์ดํผ ์ฟผ๋ฆฌ ๋ฌธ์ ์์ $N$์ฐจ์ ๋์ ํฉ ์์ด๋์ด๋ ์จ๋ณธ์ ์ด ์์๋๋ฐ, ์ด๊ฒ์ด SOS DP์ ๊ฐ๋ค๋ ๊ฒ์ด ์ ๊ธฐํ๋ค. ์์ผ๋ก๋ ํฌํจ๋ฐฐ์ ์์ ๋ญ๊ฐ ์ค์ด๊ณ ์ถ์ผ๋ฉด ํ๋ฒ์ฉ์ ์์ฌํด๋ณด๋๊ฑธ๋ก? imos-hanbyul Trick # ์ด์ ๋น์ทํ ๋ด์ฉ์ https://qwerasdfzxcl.tistory.com/35 ์ฌ๊ธฐ์ ๋ณธ์ ์ด ์๋ค. ์ง๊ธ ๋น์ฅ์ ์ดํดํ๊ธฐ ๊ท์ฐฎ์ผ๋ฏ๋ก ์ดํดํ ๋ด์ฉ์ ๋์ค์ ์ถ๊ฐํ๊ฒ ๋ค. โ์ง๋ฌธ ์ฌํญ # ๐ ์ฐธ๊ณ ์๋ฃ # https://codeforces.com/blog/entry/45223 https://blog.queuedlab.com/posts/sos-dp https://qwerasdfzxcl.tistory.com/35