[BOJ] #1450 ๋ƒ…์ƒ‰๋ฌธ์ œ (์ด๋ถ„ ํƒ์ƒ‰, Python)

๋ฐ˜์‘ํ˜•

๐ŸŒฑ ๋ฌธ์ œ

 

1450๋ฒˆ: ๋ƒ…์ƒ‰๋ฌธ์ œ

์ฒซ์งธ ์ค„์— N๊ณผ C๊ฐ€ ์ฃผ์–ด์ง„๋‹ค. N์€ 30๋ณด๋‹ค ์ž‘๊ฑฐ๋‚˜ ๊ฐ™์€ ์ž์—ฐ์ˆ˜, C๋Š” 109๋ณด๋‹ค ์ž‘๊ฑฐ๋‚˜ ๊ฐ™์€ ์Œ์ด ์•„๋‹Œ ์ •์ˆ˜์ด๋‹ค. ๋‘˜์งธ ์ค„์— ๋ฌผ๊ฑด์˜ ๋ฌด๊ฒŒ๊ฐ€ ์ฃผ์–ด์ง„๋‹ค. ๋ฌด๊ฒŒ๋„ 109๋ณด๋‹ค ์ž‘๊ฑฐ๋‚˜ ๊ฐ™์€ ์ž์—ฐ์ˆ˜์ด๋‹ค.

www.acmicpc.net

 

๐ŸŒฑ ํ’€์ด

1. ๊ธฐ์กด Bruteforce๋กœ ํ’€ ์ˆ˜ ์—†๋Š” ์ด์œ 

์ด ๋ฌธ์ œ๋Š” ๋ฌผ๊ฑด์˜ ๊ฐœ์ˆ˜(n)๊ฐ€ ์ตœ๋Œ€ 30๊ฐœ ์ฃผ์–ด์ง‘๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์ด ๋ฌธ์ œ๋ฅผ ์™„์ „ ํƒ์ƒ‰์œผ๋กœ ํ‘ผ๋‹ค๋ฉด ๋ฌผ๊ฑด ํ•˜๋‚˜ํ•˜๋‚˜๋งˆ๋‹ค ๋„ฃ์„์ง€ ์•ˆ๋„ฃ์„์ง€ ๋ชจ๋“  ๊ฒฝ์šฐ๋ฅผ ์„ธ๋ฉด ์ตœ๋Œ€ 230๋ฒˆ์˜ ์—ฐ์‚ฐ์„ ํ•˜๊ฒŒ ๋˜๋Š”๋ฐ, ์ด๋Š” 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๋ผ๋ฉด, ์ „์ฒด ์กฐํ•ฉ์„ ๊ตฌํ•˜๋ฉด 4C0+4C1+4C2+4C3+4C4=16๊ฐœ๊ฐ€ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ ˆ๋ฐ˜์œผ๋กœ ๋ถ„ํ• ํ•˜์—ฌ ์กฐํ•ฉ์„ ๊ตฌํ•˜๋ฉด (1, 2)์˜ ์กฐํ•ฉ 4๊ฐœ, (2, 3)์˜ ์กฐํ•ฉ 4๊ฐœ๋กœ ์ด 8๊ฐœ ๋ฐ–์— ๋‚˜์˜ค์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
    ์ฆ‰, ์—ฐ์‚ฐ์˜ ํšŸ์ˆ˜๊ฐ€ O(2n)์—์„œ O(2n2)์œผ๋กœ ์ค„์–ด๋“ค๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

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)

 

+) ์ฐธ๊ณ 

 

[์•Œ๊ณ ๋ฆฌ์ฆ˜ ๊ธฐ๋ฒ•] Meet In The Middle

Meet In The Middle ๊ธฐ๋ฒ•(๋ฐฑ์ค€ 1208)

velog.io

 

๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€