https://www.acmicpc.net/problem/16987
16987번: 계란으로 계란치기
원래 프로그래머의 기본 소양은 팔굽혀펴기를 단 한 개도 할 수 없는 것이라고 하지만 인범이는 3대 500을 넘기는 몇 안되는 프로그래머 중 한 명이다. 인범이는 BOJ에서 틀린 제출을 할 때마다 턱
www.acmicpc.net
1. 해결방법
문제를 이해하면 백트레킹이라는 것을 알 수 있지만, 이해도 어렵고 문장도 길어서 어떤 알고리즘인지 찾아내기가 꽤 어려웠다.
문제 이해하는데만 20~30분 정도는 걸린 것 같다.
이 문제에 대한 접근은 왼쪽부터 계란을 집어서 다른 계란을 때리는 것이다.
이 때, 내구도와 무게에 따라 들고있는 계란이 깨지는지 다른 계란이 깨지는지의 경우를 고려해야한다.
조건을 생각해 보면,
1. 들고 있는 계란이 깨진 경우,
2. 들고있는 계란을 제외한 모든 계란이 깨진 경우,
위 두 조건을 재귀를 돌때마다 체크를 해주어야 한다.
그리고 이 문제는 방문 체크를 권장하지 않는다. 그 이유는 들고 있는 계란이 모든 계란을 때려봐야 하기 때문에 인덱스를 기준으로 유효성 검사를 해주는 것이 좋다.
2. 정답코드
import sys
from collections import deque
input = sys.stdin.readline
N = int(input())
eggs = []
for _ in range(N):
eggs.append(list(map(int, input().split())))
chk = [False] * N
def dfs(idx):
global answer
# 종료 지점
if idx == N:
count = 0
for i in range(N):
if eggs[i][0] <= 0:
count += 1
answer = max(answer, count)
return
# 들고 있는 계란이 깨진 경우,
if eggs[idx][0] <= 0:
dfs(idx + 1)
return
# 들고있는 계한 제외하고 나머지 계란이 다 깨져있는 경우,
for i in range(N):
if i != idx:
if eggs[i][0] > 0:
break
else:
answer = max(answer, N - 1)
return
# 떄리기
for i in range(N):
if i != idx and eggs[i][0] > 0:
eggs[idx][0] -= eggs[i][1]
eggs[i][0] -= eggs[idx][1]
dfs(idx + 1)
eggs[idx][0] += eggs[i][1]
eggs[i][0] += eggs[idx][1]
answer = 0
dfs(0)
print(answer)
[참고]
'Algorithm > BOJ' 카테고리의 다른 글
[BOJ] 12891. DNA 비밀번호 Python, Java (0) | 2023.02.09 |
---|---|
[BOJ] 11660. 구간 합 구하기5 Python, Java (0) | 2023.02.09 |
[BOJ] 4358. 생태학 Python (0) | 2023.02.05 |
[BOJ] 2075. N번째 큰 수 Python (0) | 2023.02.05 |
[BOJ] 11279. 최대 힙 Python, Java (0) | 2023.02.03 |