Bitmask Technique
μ΄λ² ν¬μ€νΈλ PS ν ν¬λ μ€ νλμΈ λΉνΈλ§μ€ν¬(Bitmask) κΈ°λ²μ λ€λ£Ήλλ€. Bitmask κΈ°λ²μ μ΄μ§μ(bit)μ μ΄μ§μ μ°μ°(bitwise operation)μ νμ©ν΄ μ°μ°μμ ν° μ΄λμ μ 곡νκΈ° λλ¬Έμ κ³ κΈ PSλ₯Ό μν΄μλ κΌ μ΅νμΌ νλ κΈ°λ²μ λλ€.
μ΄μ§μμ μ΄μ§μ μ°μ°, κ·Έλ¦¬κ³ μ§ν© νν
μ»΄ν¨ν°κ³΅νμ 곡λΆνλ€λ©΄, μ΄μ§μμ μμ§μ λ³νμ λν΄ μ΄λ―Έ λΉ μνκ² μκ³ μμ κ²μ΄λ€. λ, &
(AND), |
(OR), ~
(NOT)κ³Ό κ°μ Bitwise μ΄μ§μ μ°μ°μ λν΄μλ μ΄λ―Έ μ΅μν κ²μ΄λ€. Bitmaskλ μ΄μ§μ νκΈ°λ²κ³Ό μ΄μ§μ μ°μ°λ€μ ν΅ν΄ βμ§ν©βμ νννλ κΈ°λ²μ΄λ€.
μ§ν©μ ννμ Boolean Arrayλ‘ κ°λ₯νλ€. bool mySet[100]
κ³Ό κ°μ μ½λμμ λͺλ²μ§Έ λΉνΈκ° μΌμ‘λμ§, κΊΌμ‘λμ§λ‘ μ§ν©μ ννν μ μλ€. λ§μ½ 2, 3, 5λ²μ§Έ λΉνΈκ° μΌμ Έμλ€λ©΄, 2, 3, 5λ²μ§Έ μμκ° μ‘΄μ¬νλ μ§ν©μ λ§νλ€.
(Boolean Array)
| 0 | 1 | 1 | 0 | 1 | ...
κ·Έλ¬λ μ΄κ²μ Boolean Array λμ Integer νλλ‘λ ννμ΄ ν μ μλ€.
(Integer)
01101...
CμΈμμ int
ν λ³μμ 4 λ°μ΄νΈ, μ¦ 32 bitμ΄κΈ° λλ¬Έμ 32κ° μμλ₯Ό κ°λ λΆλΆμ§ν©μ Integer λ³μ νλλ‘ ννν μ μλ€. λ ν° μ§ν©μ ννν΄μΌ νλ€λ©΄, int
λμ long long
μ μΈ μ μλ€. κ·Έλ¬λ©΄ 8 λ°μ΄νΈ, μ¦ 64κ° μμμ λΆλΆμ§ν©μ ννν μ μλ€.
Bitmask μ§ν©μ μ°μ°
Bitmask κΈ°λ²μ κ°μ₯ ν° μ₯μ μ Bitwise μ°μ°μ ν΅ν΄ μ§ν© μ°μ°μ λΉ λ₯΄κ² μνν μ μλ€λ μ μ μλ€.
1. 곡μ§ν©
int A = 0
2. κ½ μ°¬ μ§ν©
int A = (1 << 10) - 1
int N = (size of your set)
int A = (1 << N) - 1
3. μμ μΆκ°
A
λΌλ Bitmask μ§ν©μ k
λ²μ§Έ μμλ₯Ό μΆκ°
0101 | 0010 -> 0111
A | (1 << k)
4. μμ μμ
A
λΌλ Bitmask μ§ν©μ k
λ²μ§Έ μμλ₯Ό μμ . μμ μ½μ
λμ μ°μ°μ λ°λκ²μ μννλ©΄ λλ€.
0101 & ~(0100) -> 0101 & (1011) -> 0001
A & ~(1 << k)
5. μμ μΆμΆ
A
λΌλ Bitmask μ§ν©μ k
λ²μ§Έ μμμ μ‘΄μ¬μ¬λΆλ₯Ό μΆμΆ
if(0101 & 0100) -> if(0100) -> True
if(0101 & 0010) -> if(0000) -> False
A ^ (1 << k)
6. μμ ν κΈ
A
λΌλ Bitmask μ§ν©μ k
λ²μ§Έ μμλ₯Ό ν κΈ
0101 ^ 0100 -> 0001
A ^ (1 << k)
μ§κΈκΉμ Bitmask μ§ν© μ°μ° μ€μ λ°λ³΅ν΄μ 보μ΄λ ν¨ν΄μ (1 << k)
μλ€. νΉμ μμλ₯Ό λ€λ£¨κΈ° μν΄μ (1 << k)
λ₯Ό μ΄λ€λ μ , κΈ°μ΅ν΄λμ.
7. μ§ν© μ¬μ΄ μ°μ°
A | B
: A, Bμ ν©μ§ν©. $A \cup B$A & B
: A, Bμ κ΅μ§ν©. $A \cap B$A & (~B)
: A, Bμ μ°¨μ§ν©. $A - B$A ^ B
: Aμ B, λ μ€ νλμλ§ ν¬ν¨λ μμλ€μ μ§ν©.
λ§μ½ μ§ν©μ Boolean Arrayλ‘ νννλ€λ©΄, μμ μ§ν© μ°μ°λ€μ μννλλ° $O(n)$μ μκ°μ΄ κ±Έλ¦°λ€, κ·Έλ¬λ Bitmask μ§ν© κΈ°λ²μ μ΄λ€λ©΄, $O(1)$μ λΉμ©λ§ λ€ λΏμ΄λ€!
μμ λ° νμ©
μ§κΈκΉμ§ κΈ°λ³Έμ μΈ Bitmask μ§ν© μ°μ°λ€μ μ΄ν΄λ³΄μλ€. μ΄λ²μλ Bitmaskλ₯Ό μ°λ λνμ μΈ λ¬Έμ μΈ [μΈνμ λ¬Έμ ]μ Bitmask μ°μ°μ νμ©λ€μ μ΄ν΄λ³΄μ.
μΈνμ λ¬Έμ
μΈνμ λ¬Έμ μμλ λ°©λ¬Έν λμλ₯Ό Bitmask μ§ν©μΌλ‘ νννλ€. μλ₯Ό λ€μ΄ 001010
μ΄λΌλ©΄ 2λ²μ§Έ, 4λ²μ§Έ λμλ₯Ό λ°©λ¬Έν κ²μ΄ λλ€. λ°μ μ체λ μΈνμ λ¬Έμ ν¬μ€νΈμμ νμΈνκ³ DPμμ μ°λ μ νμλ§ λ°λ‘ μ¨λ³΄λ©΄ μλμ κ°λ€.
λ§μ½ visited
λ₯Ό Bitmask μ§ν©μ΄ μλλΌ Boolean Arrayλ‘ νννλ€λ©΄, μμ κ°μ λΆλΆμ§ν©μ κΈ°λ°μΌλ‘ νλ μ νμμ ꡬννλκ² μμ£Ό κΉλ€λ‘μ μ κ²μ΄λ€. Bitmask μ§ν©μ μ¬μ©νλ©΄, μ§ν© $S$μ λν λΆλΆμ μ μ λ³μλ‘ μ½κ² ννν μ μλ€.
dp[curr][visited] = min(dp[prev, visited - prev] + w[prev][curr])
λ¨, μ΄λ²μ μ΄ν΄λ³Έ DP+Bitmaskμ μΈνμ λ¬Έμ λ λ°©λ¬Ένλ λμμ μκ° μ΅λ 16κ°λ‘ μλΉν μ λ€. λ§μ½ λ°©λ¬Έν΄μΌ νλ λμ μκ° Integer λ³μμ νν λ²μλ₯Ό λ²μ΄λλ€λ©΄, Bitmask μ§ν© κΈ°λ²μ μΈ μ μλ€λ μ μ μ μνμ.
νμ©
Bitmask μ§ν© κΈ°λ²μ μΆκ°μ μΈ νμ©λ²μ λν΄ μ΄ν΄λ³΄μ.
8. μ΅μ μμ μΆμΆ
μ΄μ§μ A
μ μμ -A
λ 2μ 보μ ννλ²μ μν΄ ~A + 1
λ‘ ννλλ€. μ΄μ§μ A
μ κ°μ₯ μ€λ₯Έμͺ½ λΉνΈ k
μ λν΄ μ€λ₯Έμͺ½μ λͺ¨λ 0μΌλ‘ ννλλλ°, ~A
μ°μ°μ k
λ₯Ό 0μΌλ‘ κ·Έλ¦¬κ³ κ·Έ μ€λ₯Έμͺ½μ λͺ¨λ 1λ‘ λ°κΎΌλ€. μ¬κΈ°μ 1μ λν΄μ£Όκ² λλ©΄, k
λ³΄λ€ μ€λ₯Έμͺ½μ μλ bitλ λͺ¨λ 0μ΄ λκ³ , k
λ²μ§Έ λΉνΈλ λ€μ 1μ΄ λμ§λ§, k
μ μΌμͺ½μ μλ λΉνΈλ ~A
μ μν΄ ν κΈλ μ±λ‘ κ·Έλλ‘ μλ€.
A = 011011000
-A = -(011011000) -> ~(011011000) + 1 (2μ 보μ) -> (100100111) + 1 -> 100101000
A & (-A) = 011011000 & 100101000 -> 000001000
int first = A & (-A)
9. μ΅μ μμ μμ
011011000 & (011011000 - 1) -> 011011000 & (011010111) -> 011010000
A &= (A - 1)
A-1
μ νκ² λλ©΄, κ°μ₯ μ€λ₯Έμͺ½μ μλ bitλ 0μ΄ λκ³ , κ·Έλ³΄λ€ μ€λ₯Έμͺ½μ μλ bitλ λͺ¨λ 1μ΄ λλ€. μ΄λ₯Ό νμ©ν΄ μ΅μ μμλ₯Ό μμ νλ€.
10. λͺ¨λ λΆλΆμ§ν© μν
for (int subset = A; subset; subset = (subset - 1) & A) { ... }
A = 1011
[subset]
1011 (μ΄κΈ°κ°)
(1011 - 1) & 1011 -> 1010 & 1011 -> 1010
(1010 - 1) & 1011 -> 1001 & 1011 -> 1001
(1001 - 1) & 1011 -> 1000 & 1011 -> 1000
(1000 - 1) & 1011 -> 0111 & 1011 -> 0011
(0011 - 1) & 1011 -> 0110 & 1011 -> 0010
A
λΌλ μ§ν©μ λΆλΆμ§ν©μ μννλ μ½λλ€. λ³ΈμΈμ μΌμ’
μ ν
ν¬λμΌλ‘ λ°μλ€μ΄κ³ μ°κ³ μλ€. μμ μ½λλ A
λΌλ μ§ν©μ λΆλΆμ§ν©μ μννλ μ½λμΈλ°, μ½κ° λ³νν΄ μ 체 μ§ν©μ μννλ μ½λλ λ§λ€ μ μλ€.
for (int subset = 0, subset < (1 << N); subset++) { ... }