1. 언어 : JAVA
2. 난이도 : Gold 4
3. 풀이
일단 가장 중요한건 이 문제가 DP라는 걸 알아야한다는 것이다.
(본인은 Memoization을 사용하긴했다.)
DP를 위해서 DP 배열의 정의를 먼저 내려야하는데, 출석을 몇일했는지는 의미가 없고, 우리는
결석을 몇번했는지, 지각은 몇번했는지, 또 그 결석이 연속됐는지가 중요하다.
그렇기 때문에 DP[날짜][지각횟수][결석횟수]
로 잡아주고 DP[1001][3][4] 로 선언을 해주게 된다. (N<1001, 지각 최대 2번, 결석 최대 3번)
그래서 우리는 재귀를 이용할 건데.
1. 출석했을때 : DP[date+1][late][abs]
2. 지각했을때 : DP[date+1][late+1][abs]
3. 결석했을때 : DP[date+1][late][abs+1]
로 케이스를 나눌 수 있다. 모~든 케이스를 탐색하도록 재귀를 만들고 기저사례를 만들고,
Memoization 코드를 넣으면 끝이다.
4. 소스코드
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class Main {
public static int N = 0;
public static long [][][] dp = null;
public static void main(String [] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
N = Integer.parseInt(br.readLine());
dp = new long[1001][3][4];
for(int i=0; i<=1000; i++) {
for(int j=0; j<=2; j++) {
for(int z=0; z<=3; z++) {
dp[i][j][z] = -1;
}
}
}
long result = search(1, 0, 0) + search(1, 1, 0) + search(1, 0, 1);
System.out.println(result%1000000);
}
public static long search(int day, int late, int abs) {
if(dp[day][late][abs] != -1) {
return dp[day][late][abs]%1000000;
}
if(late == 2 || abs == 3) {
dp[day][late][abs] = 0;
return 0;
}
if(N == day) {
dp[day][late][abs] = 1;
return 1;
}
long result = 0;
result += (search(day+1, late+1, 0) + search(day+1, late, abs+1) + search(day+1, late, 0)) % 1000000;
dp[day][late][abs] = result;
return result%1000000;
}
}
'Algorithm > Dynamic Programing' 카테고리의 다른 글
| BOJ No.1577[도로의 개수] (0) | 2021.03.31 |
|---|
