728x90
14889번: 스타트와 링크
예제 2의 경우에 1,3,6, 2,4,5로 팀을 나누면 되고, 예제 3의 경우에는 1,2,4,5, 3,6,7,8로 팀을 나누면 된다.
www.acmicpc.net
문제 설명
- 짝수 N명의 사람들을 두개의 팀으로 나누어 각 팀의 능력치를 계산해 비교해 차이가 최소인 팀 구성을 구하는 문제
- 팀이 구성되면 구성원 끼리 순서가 없기 때문에 조합을 찾는 문제로 생각해 풀 수 있음
고민한 부분
- python의 내장 라이브러리인
itertools
의combinations
함수를 사용할 수 있을지 확인해보고 싶었다 - 백트래킹 문제가 조금 까다롭게 나오는 경우 중간에 탐색할 필요 없는 조건을 찾아 가지치기를 해주어야 하는데 이 문제에서는 가지치기 할 필요 없이 조합을 구하면 되는 문제였기 때문에 내장 함수를 사용해 풀이해도 통과가 됐다
- 아래 재귀 형태로 조합을 구하는 코드와 내장 함수를 사용하는 코드를 모두 첨부했다
재귀로 조합 구하기
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import sys, math | |
from itertools import permutations | |
def cal_performanceteam:list: | |
performance = 0 | |
for i in team: | |
for j in team: | |
if i == j: | |
continue | |
performance += TABLE[i][j] | |
return performance | |
def compare_performA:list,B:list: | |
"""스타트 팀과 링크 팀의 능력치 차이 계산 | |
Args: | |
A list: 스타트 팀원 리스트 | |
B list: 링크팀 팀원 리스트 | |
Return: | |
differ int: 능력치 차이 | |
""" | |
return abscalperformance(A- cal_performanceB) | |
def DFSteamA:list: | |
global min_ | |
if lenteamA == N//2: | |
# 차이 값 계산 & 최소값 업데이트 | |
team_B = [p for p in people if p not in team_A] | |
min_ = minmin,compareperform(teamA,teamB) | |
return | |
## 두번 계산되는 문제 | |
### ex) A = [1,2], b = [0,3] // A = [0,3], B = [1,2]는 같은 상황 | |
for i in rangeteamA[−1],N: | |
if i in team_A: | |
continue | |
team_A.appendi | |
DFSteamA | |
team_A.pop | |
if __name__ == '__main__': | |
turn_in = 1 | |
if turn_in ==0: | |
sys.stdio = open′testcase.txt′ | |
N = intsys.stdio.readline() | |
TABLE = [listmap(int,sys.stdio.readline(.split)) for _ in rangeN] | |
else: | |
N = intsys.stdin.readline() | |
TABLE = [listmap(int,sys.stdin.readline(.split)) for _ in rangeN] | |
people = listrange(N) | |
min_ = math.inf | |
for i in rangeN//2: | |
DFS[i] | |
printmin_ | |
python 내장 함수 combinations 사용해 조합 구하기
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import sys, math | |
from itertools import combinations | |
def cal_performanceteam:list: | |
performance = 0 | |
for i in team: | |
for j in team: | |
if i == j: | |
continue | |
performance += TABLE[i][j] | |
return performance | |
def compare_performA:list,B:list: | |
"""스타트 팀과 링크 팀의 능력치 차이 계산 | |
Args: | |
A list: 스타트 팀원 리스트 | |
B list: 링크팀 팀원 리스트 | |
Return: | |
differ int: 능력치 차이 | |
""" | |
return abscalperformance(A- cal_performanceB) | |
def solve: | |
"""팀나누기 + 차이 최소값 구하는 main 함수 | |
Returns: | |
_type_: _description_ | |
""" | |
min_ = math.inf | |
#팀 나누기 | |
A_teams = combinationspeople,N//2 # A팀 조합 리스트, B팀은 for문 안에서 새로 | |
for A_team in A_teams: | |
B_team = [p for p in people if p not in A_team] | |
diff = compare_performAteam,Bteam | |
min_ = mindiff, min_ | |
return min_ | |
if __name__ == '__main__': | |
turn_in = 1 | |
if turn_in ==0: | |
sys.stdio = open′testcase.txt′ | |
N = intsys.stdio.readline() | |
TABLE = [listmap(int,sys.stdio.readline(.split)) for _ in rangeN] | |
else: | |
N = intsys.stdin.readline() | |
TABLE = [listmap(int,sys.stdin.readline(.split)) for _ in rangeN] | |
people = listrange(N) | |
printsolve() |
'알고리즘 공부 > 백준 문제풀이' 카테고리의 다른 글
[python 백준] 15685번 드래곤 커브 0 | 2022.08.07 |
---|---|
[백준 python] 14501번 퇴사 0 | 2022.08.05 |
[백준 python] 14891번 톱니바퀴 0 | 2022.08.05 |
[백준 python] 14502번 연구소 0 | 2022.08.02 |
[백준 python] 14503번 로봇 청소기 0 | 2022.08.02 |