이번 문제는 백준의 골드 5 문제 레벨 햄버거이다.
문제를 차근차근 읽어보도록 하자.
최대 50
까지의 햄버거 레벨이 주어진다.
각 햄버거 레벨의 구성은 번 (L-1) 패티 (L-1) 번
으로 이루어진다.
예를 들어, 레벨 1의 버거는 번 L0 패티 L0 번
으로 구성되는 것이다.
상근이가 아래부터 X
장을 먹었을 때, 몇 장의 패티를 먹었는지 구해라!
어떻게 문제를 풀어야 할까?
분할 정복
문제를 읽었을 때 가장 먼저 떠오르는 것은 분할 정복
이다.
레벨 2의 햄버거가 번 L1 패티 L1 번
과 같이 구성될 것이니, 재귀적이다.
하지만 아래로부터 몇 장의 패티를 먹었는지 어떻게 계산할까?
직접 BPPPB
와 같은 문자열을 재귀를 통해 만드는 것은 시간이 너무 오래걸릴 것 같다.
그도 그럴 것이 50
레벨의 햄버거를 만드는 데는 너무너무 큰 수의 패티와 번이 들어간다.
아래와 같이 30
레벨의 햄버거를 만드는 데에 들어가는 장 수만 이미 42억
장에 달한다.
입력 및 출력해야 하는 수는 long long
타입이면 2^63 - 1
이 최대이기에, 상관없을 것이다.
그 말인 즉, 어떤 수학적 계산을 통해서 빠르게 계산을 해내야 한다는 말인 것 같다.
규칙 찾기
계속 관찰하고 생각하다보니, 규칙을 만들 수 있을 것 같다.
우선 알아낼 수 있는 것은 햄버거 장수의 점화식이다.
재귀적 구성이기 때문에, (L-1) * 2 + 3
장 이라는 간단한 점화식을 도출할 수 있다.
또한, 패티의 수는 매 레벨 당 (L-1) * 2 + 1
장 이라는 점화식이 도출된다.
이로써 모든 단계의 총 장수, 패티 장수는 구해서 저장할 수 있게 되었다.
이제부터 패티를 먹게되는 규칙을 잘 생각해보자.
우선 당연히 1
장을 먹는 경우는 레벨 0을 제외하면 모두 0이 답이다.
그럼 이제 아래와 같이 햄버거가 있을 때, 붉은 선 아래로 먹는 경우엔 어떨까?
L-1
레벨의 햄버거에서 한 번더 계산을 해야할 것 같다.
즉 재귀적으로 L-1
레벨의 햄버거로 내려가서 패티의 수를 생각한다.
그럼 처음에 입력받았던 N, X
에 대해서 N-1, X-1
이 되는 것이다.
X
가 하나 줄어드는 이유는, 앞의 번
이 하나 줄어들기 때문이다.
만약 붉은 선이 좀 더 길어져서, 한 가운데의 패티까지 먹는다면?
이 규칙은 매우 간단하게, L-1
햄버거의 패티 + 가운데 패티가 답이 된다.
붉은 선이 더더 길어져서 뒤에 나오는 L-1
햄버거 아래로 먹는 경우엔?
이 경우엔 좀 더 복잡해진다.
간단하게 생각해볼 수 있는 건, 앞의 L-1
패티와 중앙 패티 1장은 반드시 먹을 수 있다.
이제 거기에 L-1
패티에 대해서 재귀적인 계산이 들어가야 한다.
가장 처음엔 N-1, X-1
이었지만, 이번엔 X-1
이 아니다.
N-1
은 맞지만, 먹는 장 수가 X - ((L-1 Burger) + 2)
가 되어야 한다.
왜? 정 가운데의 패티까지는 이미 다 먹었다고 생각하는 것이기 때문이다!
마지막 경우인 끝까지 다먹어버리는 경우다.
이 경우엔 당연하게도, 버거에 존재하는 모든 패티를 다 먹을 수 있다.
따라서 이전에 저장해놓은 patties[N]
이 된다!
최종적으로 아래와 같이 코드를 작성했다.
어렵다 어려워 DP!