백준 - 개근상(1563)

marafo·2021년 1월 10일
0

Dynamic Programming

문제

백준중학교에서는 학기가 끝날 무렵에 출결사항을 보고 개근상을 줄 것인지 말 것인지 결정한다. 이 학교는 이상해서 학생들이 학교를 너무 자주 빠지기 때문에, 개근상을 주는 조건이 조금 독특하다.

출결사항이 기록되는 출결은 출석, 지각, 결석이다.

개근상을 받을 수 없는 사람은 지각을 두 번 이상 했거나, 결석을 세 번 연속으로 한 사람이다.

한 학기가 4일이고, O를 출석, L을 지각, A를 결석이라고 했을 때, 개근상을 받을 수 있는 출결정보는

OOOO OOOA OOOL OOAO OOAA OOAL OOLO OOLA OAOO OAOA 
OAOL OAAO OAAL OALO OALA OLOO OLOA OLAO OLAA AOOO 
AOOA AOOL AOAO AOAA AOAL AOLO AOLA AAOO AAOA AAOL
AALO AALA ALOO ALOA ALAO ALAA LOOO LOOA LOAO LOAA 
LAOO LAOA LAAO

총 43가지이다.

한 학기는 N일이다. N이 주어졌을 때, 개근상을 받을 수 있는 출결정보의 개수를 세는 프로그램을 작성하시오.

입력

첫째 줄에 N이 주어진다. N은 1,000보다 작거나 같다.

출력

첫째 줄에 정답을 1,000,000으로 나눈 나머지를 출력한다.


import sys
sys.setrecursionlimit(10**6)

N = int(input())

dp=[[[-1 for absent in range(3)] for late in range(2)] for day in range(N + 1)]

# 역방향 DP => 가장 마지막 깊이(day4)부터 누적해서 day 1까지 만든다 
def dfs(day, late, absent):
	if (late == 2) or (absent == 3): # 지각 2번 or 결석연속3 번
		return 0

	if day == N:
		return 1 # 가능한 케이스가 1개 늘어난다.

	if dp[day][late][absent] == -1: # 참석 + 지각 + 결석
		attend = dfs(day + 1, late, 0) + dfs(day + 1, late + 1, 0) + dfs(day + 1, late, absent + 1)
		dp[day][late][absent] = attend

		return attend
	else:
		return dp[day][late][absent]
            
print((dfs(0, 0, 0)) % 1000000)

참고)
https://daimhada.tistory.com/179

profile
프론트 개발자 준비

0개의 댓글