[BOJ] 15661 링크와 스타트
브루트 포스
이 문제는 팀을 2개로 나눠서 각 팀원의 전력의 차이가 최소가 되도록 구현하는 문제인데, 팀원 수에 제한이 없다. 그래서 어떻게 풀어야 할까 고민을 하다가, 방법이 없고 완전탐색을 해야 함을 깨달았다.
완전 탐색을 해도, $21 C 10$ 으로 35만개의 조합이 나오는데, 이를 각각 계산해서 구해도 시간초과가 아슬아슬하게 나오지 않을 것이라고 생각했다. $21C10$ 인 이유는, 20C2 + ... + 20C10
을 구해도 더 큰 값으로 시간복잡도의 워스트 케이스를 고려한 것이다.
구현
아래 코드는 python3에서는 시간초과를 받았다 ㅜ.ㅜ 중복 문제가 포함되어 있어서 그런 것 같다. 어떻게 해결해야 할지 고민해봐야겠다.
pypy3로는 통과했다.
import sys
def calculate(array):
result = 0
for i in range(len(array)):
for j in range(i+1, len(array)):
result += graph[array[i]][array[j]] + graph[array[j]][array[i]]
return result
def backtrack(full, depth, first, visited, n, start):
global answer
if depth == full:
second = []
for i in range(n):
if not visited[i]:
second.append(i)
answer = min(answer, abs(calculate(first) - calculate(second)))
return
for i in range(start, n):
# first team 에 넣어
if visited[i]:
continue
first.append(i)
visited[i] = True
backtrack(full, depth+1, first, visited, n, i)
first.pop()
visited[i] = False
def solution(n):
first = []
visited = [False] * n
for i in range(2, n//2+1): # first team 인원 수
backtrack(i, 0, first, visited, n, 0)
if __name__ == "__main__":
answer = int(1e9)
N = int(sys.stdin.readline().rstrip())
graph = []
for _ in range(N):
graph.append(list(map(int, sys.stdin.readline().rstrip().split())))
solution(N)
print(answer)