728x90
https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV5V1SYKAaUDFAWu
SW Expert Academy
SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!
swexpertacademy.com
재귀를 이용한 조합으로 풀었다. 해당 행을 모두 0으로 바꾸고 재귀를 타고 들어가거나, 1로 바꾸고 재귀를 타고 들어가거나 원상 복귀 시키고(아무것도 하지 않고) 다음 행으로 넘어가는 식으로 풀면 된다.
처음에는 원상복귀 시키고 또 재귀를 타고 들어갔는데, 굳이 그렇게 해주지 않아도 for 문을 돌기 때문에 원상복귀한 상태 (아무것도 하지 않은 상태)로 다음 행으로 넘어간다. 이는 상태 트리를 그려보면 간단하게 알 수 있다.

각 solve 함수를 호출하자마자 k_check()로 체크해주기 때문에 모든 행 조합을 확인 할 수 있으며, cnt가 0 즉, 아무 약품도 바르지 않아도 되는 경우(맨 처음 호출된 solve)를 미리 체크해줄 수 있다.
def k_check(): # K개 연속 체크 함수
for j in range(W):
first_char = film[0][j]
check = 0
for i in range(D):
if first_char == film[i][j]:
check += 1
else:
first_char = film[i][j]
check = 1
if check >= K: # 한 열에 연속한 특성이 K보다 크면 더 볼 것 없음
break
if check < K: # 한 열에 연속한 특성이 K개보다 작으면 더 볼 것도 없음
return False
return True
def solve(cnt, change_idx): # 재귀를 이용한 조합
global min_cnt
if k_check(): # 함수 실행하자마자 연속 K개가 있는지 체크 (약품을 안 발라줘도 될 경우를 위한 가지치기)
min_cnt = min(cnt, min_cnt)
return
if cnt >= min_cnt: # 가지치기
return
for i in range(change_idx+1, D):
origin_film = film[i][:]
for j in range(W): # 특성 변경
film[i][j] = 1
solve(cnt+1, i)
for j in range(W): # 특성 변경
film[i][j] = 0
solve(cnt+1, i)
for j in range(W): # 원상 복귀
film[i][j] = origin_film[j]
for tc in range(1, int(input())+1):
D, W, K = map(int, input().split())
film = [list(map(int, input().split())) for _ in range(D)]
min_cnt = D+1
solve(0, -1)
print('#{} {}'.format(tc, min_cnt))
'알고리즘' 카테고리의 다른 글
[백준] 1043. 거짓말 (0) | 2021.10.19 |
---|---|
[백준] 17352. 여러분의 다리가 되어 드리겠습니다! (0) | 2021.10.17 |
[SWEA] 1249. 보급로 (0) | 2021.10.17 |
[백준] 15686. 치킨 배달 (0) | 2021.10.17 |
최소 신장 트리 - Prim's algorithm (0) | 2021.10.16 |