๐ฑ ๋ฌธ์
๐ฑ ํ์ด
1. ๊ธฐ์กด Bruteforce๋ก ํ ์ ์๋ ์ด์
์ด ๋ฌธ์ ๋ ๋ฌผ๊ฑด์ ๊ฐ์(n
)๊ฐ ์ต๋ 30๊ฐ ์ฃผ์ด์ง๋๋ค. ๋ง์ฝ ์ด ๋ฌธ์ ๋ฅผ ์์ ํ์์ผ๋ก ํผ๋ค๋ฉด ๋ฌผ๊ฑด ํ๋ํ๋๋ง๋ค ๋ฃ์์ง ์๋ฃ์์ง ๋ชจ๋ ๊ฒฝ์ฐ๋ฅผ ์ธ๋ฉด ์ต๋ $2^{30}$๋ฒ์ ์ฐ์ฐ์ ํ๊ฒ ๋๋๋ฐ, ์ด๋ 10์ต์ด ๋๋ ๊ฐ์ผ๋ก ๋ฌด์กฐ๊ฑด ์๊ฐ ์ด๊ณผ๊ฐ ๋ฐ์ํฉ๋๋ค.
๊ธฐ์กด Bruteforce๋ก ํผ๋ค๋ฉด ์ฝ๋๊ฐ ๋ค์๊ณผ ๊ฐ์ ๊ฒ์ ๋๋ค.
import sys
from itertools import combinations
input = sys.stdin.readline
n, c = map(int, input().split())
obj = list(map(int, input().split()))
sum_combination = []
for i in range(0, len(obj) + 1):
for comb in combinations(obj, i):
sum_combination.append(sum(comb))
answer = 0
for sum in sum_combination:
if sum <= c:
answer +=1
print(answer)
๋ชจ๋ ์กฐํฉ์ ๊ตฌํ ํ, ๊ทธ ํฉ์ด ๊ฐ๋ฐฉ์ ๋ฃ์ ์ ์๋ ์ต๋ ๋ฌด๊ฒ(c
)๋ณด๋ค ์์ผ๋ฉด answer
๋ฅผ 1 ์ฆ๊ฐ์ํต๋๋ค. ํ์ง๋ง ์ด ์ฝ๋๋ ๋ฌด์กฐ๊ฑด ์๊ฐ์ด๊ณผ๊ฐ ๋ฉ๋๋ค.
2. MITM ์๊ณ ๋ฆฌ์ฆ
์ด ๋ฌธ์ ๋ MITM ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํด์ ํ์ด์ผ ํฉ๋๋ค. MITM ์๊ณ ๋ฆฌ์ฆ์ Bruteforce๋ฅผ ์ฌ์ฉํ์ง๋ง ์ด๋ฅผ ๋ถํ ํด์ ์ฐ์ฐ์ ์๋ฅผ ์ค์ด๋ ์๊ณ ๋ฆฌ์ฆ์ ๋๋ค. Bruteforce ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํด์ผ ํ์ง๋ง ์์ ๋งํ ๊ฒ์ฒ๋ผ ๊ฒฝ์ฐ์ ์๊ฐ ํด ๋ ์ฌ์ฉํ ์ ์์ต๋๋ค.
MITM ์๊ณ ๋ฆฌ์ฆ: "2์๊ฐ ๊ฑฐ๋ฆฌ์ ์ด๋ ์ฌ์์น๊ตฌ๋ฅผ ์ฌ๊ท๋ ์์ , ๋๋ถ๋ถ ๋ฐ์ดํธ๋ฅผ ์ฌ์์น๊ตฌ ๋๋ค ์ฃผ๋ณ์์ ํ๋ ๊ธฐ์ต์ด ์๋ค. ์๋ก ์ง์ณ์ ํค์ด์ง ๋์ฏค ๋ง์ฝ ์ฌ์์น๊ตฌ๊ฐ ์ค๊ฐ ์ง์ ์์ ์์ฃผ ๋ง๋์คฌ๋๋ผ๋ฉด ์ฐ๋ฆฌ ๊ด๊ณ๊ฐ ๋ ์ค๋๊ฐ์๊น ํ๋ ์๊ฐ์ด ๋ฌธ๋ ๋ค์์๋ค."
n, c = map(int, input().split())
obj = list(map(int, input().split()))
left, right = obj[:n//2], obj[n//2:]
sum_combination_left, sum_combination_right = [], []
for i in range(0, len(left) + 1):
for sub in combinations(left, i):
sum_combination_left.append(sum(sub))
sum_combination_left.sort()
for i in range(0, len(right) + 1):
for sub in combinations(right, i):
sum_combination_right.append(sum(sub))
- MITM ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํ๋ ค๋ฉด ๋จผ์ ํ์ํ ์๋ฃ๋ฅผ ๋ฐ์ผ๋ก ๋ถํ ํด์ผ ํฉ๋๋ค.
- ํ์ํ ์๋ฃ(
obj
)๋ฅผ ๋ฐ์ผ๋ก ์ชผ๊ฐ์, ๋ฐ์ผ๋ก ์ชผ๊ฐ ๋ฆฌ์คํธ์์ ์กฐํฉ์ ๊ตฌํฉ๋๋ค. ๊ทธ ์กฐํฉ์ ํฉ์ ๋ชจ๋ ์๋ก์ด ๋ฆฌ์คํธ์ ๋ฃ์ด์ค๋๋ค. (์ด๊ฒ๋ง์ผ๋ก๋ ์กฐํฉ์ ๊ฐ์๊ฐ ํ์ฐํ ์ค์ด๋ค ๊ฒ์ ๋๋ค.) - ์๋ฅผ ๋ค์ด ๋ฌผ๊ฑด์ ๊ฐ์๊ฐ 4๊ฐ์ด๊ณ ๊ฐ๊ฐ์ ๋ฌด๊ฒ๊ฐ 1, 2, 3, 4๋ผ๋ฉด, ์ ์ฒด ์กฐํฉ์ ๊ตฌํ๋ฉด ${}_4 C {}_0 + {}_4 C {}_1 + {}_4 C {}_2 + {}_4 C {}_3 + {}_4 C {}_4 = 16$๊ฐ๊ฐ ๋ ๊ฒ์
๋๋ค. ํ์ง๋ง ์ ๋ฐ์ผ๋ก ๋ถํ ํ์ฌ ์กฐํฉ์ ๊ตฌํ๋ฉด (1, 2)์ ์กฐํฉ 4๊ฐ, (2, 3)์ ์กฐํฉ 4๊ฐ๋ก ์ด 8๊ฐ ๋ฐ์ ๋์ค์ง ์์ต๋๋ค.
์ฆ, ์ฐ์ฐ์ ํ์๊ฐ $O(2^n)$์์ $O(2^{\frac{n}{2}})$์ผ๋ก ์ค์ด๋ค๊ฒ ๋ฉ๋๋ค.
3. ์ด์งํ์
answer = 0
# ์ค๋ฅธ์ชฝ ๋ฌผ๊ฑด ๋๋ฉด์ ์ผ์ชฝ ๋ฌผ๊ฑด ๊ฐ์ ธ์ฌ ์ ์๋ ๊ฒฝ์ฐ์ ์ ํฉํ๊ธฐ
for i in sum_combination_right:
if i > c:
continue
start = 0
end = len(sum_combination_left)
while start < end:
mid = (start + end) // 2
# ์ผ์ชฝ ๋ฌผ๊ฑด๊ณผ ์ค๋ฅธ์ชฝ ๋ฌผ๊ฑด์ ๋ํ์ ๋ c๋ณด๋ค ํฌ๋ฉด
if sum_combination_left[mid] + i > c:
end = mid # ์ผ์ชฝ ๋ฌผ๊ฑด์์ ๊ฐ์ ธ์ค๋ ๋ฌผ๊ฑด์ ๋ฌด๊ฒ๋ฅผ ์ค์ด๊ธฐ
else:
start = mid + 1 # ์ผ์ชฝ ๋ฌผ๊ฑด์์ ๊ฐ์ ธ์ค๋ ๋ฌผ๊ฑด์ ๋ฌด๊ฒ ๋๋ฆฌ๊ธฐ
answer += end # end ์ธ๋ฑ์ค์ ๊ฐ์ด ๊ฐ์ ธ์ฌ ์ ์๋ ๋ฌผ๊ฑด์ ๊ฒฝ์ฐ์ ์
- ์์์ ๋ฐ์ผ๋ก ๋ถํ ํ ์ง๋ฃ์ ๋ํ ๋ชจ๋ ์กฐํฉ ๊ฒฝ์ฐ์ ํฉ์ ๋ฆฌ์คํธ๋ก ๋ง๋ ํ์๋ ์ด์งํ์์ผ๋ก ๊ฐ์ ธ์ฌ ์ ์๋ ์กฐํฉ์ ๊ฒฝ์ฐ๋ฅผ ์นด์ดํธ ํฉ๋๋ค.
- ์ฆ, ์ค๋ฅธ์ชฝ ๋ฌผ๊ฑด์ ๊ฒฝ์ฐ๋ฅผ ํ๋ ์ ํํ์ ๋, ์ผ์ชฝ ๋ฌผ๊ฑด์์ ๊ฐ์ ธ์ฌ ์ ์๋ ๊ฒฝ์ฐ์ ๊ฐ์๋ฅผ ์ด์งํ์์ผ๋ก ์ฐพ์ต๋๋ค.
- ์ผ์ชฝ ๋ฌผ๊ฑด์์ ์ด์งํ์์ ํด์ผ ํ๋ฏ๋ก ์ผ์ชฝ ์กฐํฉ์ ํฉ(
sum_combination_left
)์ ์ ๋ ฌ์ ํด์ฃผ์ด์ผ ํฉ๋๋ค. - ์ผ๋ฐ์ ์ธ ์ด์ง ํ์ ์๊ณ ๋ฆฌ์ฆ์ฒ๋ผ ์ผ์ชฝ ๋ฌผ๊ฑด ์กฐํฉ ๋ฆฌ์คํธ(
sum_combination_left
)์์start
,end
,mid
์ธ๋ฑ์ค๋ฅผ ์ค์ ํ ๋ค, ์ผ์ชฝ ๋ฌผ๊ฑด์์ ๊ฐ์ ธ์ค๋ ๋ฌผ๊ฑด๋ค์ ์กฐํฉ์ ํฉ๊ณผ ์ค๋ฅธ์ชฝ ๋ฌผ๊ฑด๋ค์ ์กฐํฉ์ ํฉ์ ๋ํ์ ๋,c
๋ณด๋ค ํฌ๋ฉดend
๋ฅผmid
๋ก ์ค์ฌ์ ์ผ์ชฝ ๋ฌผ๊ฑด ๋ฆฌ์คํธ์์ ๊ฐ์ ธ์ค๋ ๋ฌผ๊ฑด์ ๋ฌด๊ฒ๋ฅผ ์ค์ด๊ณ , ๊ทธ๋ ์ง ์์ผ๋ฉด ์ผ์ชฝ ๋ฌผ๊ฑด์์ ๊ฐ์ ธ์ค๋ ๋ฌผ๊ฑด์ ๋ฌด๊ฒ๋ฅผ ๋๋ฆฝ๋๋ค. - ์ด์ง ํ์์ด ๋๋๊ณ ๋ด์ ์ ์๋ ์ต๋ ๋ฌด๊ฒ๋ฅผ ์ฐพ์ผ๋ฉด
end
์ธ๋ฑ์ค์ ๊ฐ์ด ๋ค์ ธ์ฌ ์ ์๋ ๋ฌผ๊ฑด์ ๊ฒฝ์ฐ์ ์์ด๋ฏ๋กanswer
์ ๋ํด์ค๋๋ค.
๐ฑ ์ฝ๋
# usr/bin/env python
# -*- coding: utf8 -*-
# boj 1450 ๋
์ ๋ฌธ์
import sys
from itertools import combinations
input = sys.stdin.readline
n, c = map(int, input().split())
obj = list(map(int, input().split()))
left, right = obj[:n//2], obj[n//2:]
sum_combination_left, sum_combination_right = [0], [0]
if n == 1 and obj[0] <= c:
print(2)
exit()
if n == 1 and obj[0] > c:
print(1)
exit()
for i in range(1, len(left) + 1):
for sub in combinations(left, i):
sum_combination_left.append(sum(sub))
sum_combination_left.sort()
for i in range(1, len(right) + 1):
for sub in combinations(right, i):
sum_combination_right.append(sum(sub))
sum_combination_right.sort()
answer = 0
# ์ค๋ฅธ์ชฝ ๋ฌผ๊ฑด ๋๋ฉด์ ์ผ์ชฝ ๋ฌผ๊ฑด ๊ฐ์ ธ์ฌ ์ ์๋ ๊ฒฝ์ฐ์ ์ ํฉํ๊ธฐ
for i in sum_combination_right:
if i > c:
continue
start = 0
end = len(sum_combination_left)
while start < end:
mid = (start + end) // 2
# ์ผ์ชฝ ๋ฌผ๊ฑด๊ณผ ์ค๋ฅธ์ชฝ ๋ฌผ๊ฑด์ ๋ํ์ ๋ c๋ณด๋ค ํฌ๋ฉด
if sum_combination_left[mid] + i > c:
end = mid # ์ผ์ชฝ ๋ฌผ๊ฑด์์ ๊ฐ์ ธ์ค๋ ๋ฌผ๊ฑด์ ๋ฌด๊ฒ๋ฅผ ์ค์ด๊ธฐ
else:
start = mid + 1 # ์ผ์ชฝ ๋ฌผ๊ฑด์์ ๊ฐ์ ธ์ค๋ ๋ฌผ๊ฑด์ ๋ฌด๊ฒ ๋๋ฆฌ๊ธฐ
answer += end # end ์ธ๋ฑ์ค์ ๊ฐ์ด ๊ฐ์ ธ์ฌ ์ ์๋ ๋ฌผ๊ฑด์ ๊ฒฝ์ฐ์ ์
print(answer)
+) ์ฐธ๊ณ
'Algorithm > BOJ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[BOJ] #16724 ํผ๋ฆฌ ๋ถ๋ ์ฌ๋์ด (0) | 2023.03.14 |
---|---|
[BOJ] #1027 ๊ณ ์ธต ๊ฑด๋ฌผ(Bruteforce, Python) (0) | 2023.02.28 |
[BOJ] #2110 ๊ณต์ ๊ธฐ ์ค์น (์ด๋ถํ์, Python) (0) | 2023.02.26 |
[BOJ] #2252 ์ค ์ธ์ฐ๊ธฐ (Python) (0) | 2023.02.22 |
[BOJ] #1976 ์ฌํ๊ฐ์(Python) (0) | 2023.02.21 |
๋๊ธ