https://www.acmicpc.net/problem/1563
1563번: 개근상
백준중학교에서는 학기가 끝날 무렵에 출결사항을 보고 개근상을 줄 것인지 말 것인지 결정한다. 이 학교는 이상해서 학생들이 학교를 너무 자주 빠지기 때문에, 개근상을 주는 조건이 조금 독
www.acmicpc.net
#include <iostream>
#include <vector>
using namespace std;
const int divval = 1000000;
int dp[1001][2][3];
int main() {
ios::sync_with_stdio(false);
cin.tie(NULL);
int n;
cin >> n;
dp[1][0][0] = dp[1][1][0] = dp[1][0][1] = 1;
for(int i = 2; i <= n; i++){
dp[i][0][0] = (dp[i - 1][0][0] + dp[i - 1][0][1] + dp[i - 1][0][2]) % divval;
dp[i][0][1] = (dp[i - 1][0][0]) % divval;
dp[i][0][2] = (dp[i - 1][0][1]) % divval;
dp[i][1][0] = (dp[i - 1][0][0] + dp[i - 1][0][1] + dp[i - 1][0][2] + dp[i - 1][1][0] + dp[i - 1][1][1] + dp[i - 1][1][2]) % divval;
dp[i][1][1] = (dp[i - 1][1][0]) % divval;
dp[i][1][2] = (dp[i - 1][1][1]) % divval;
}
int ans = (dp[n][0][0] + dp[n][0][1] + dp[n][0][2] + dp[n][1][0] + dp[n][1][1] + dp[n][1][2]) % divval;
cout << ans << endl;
return 0;
}
dp[날짜][지각 횟수][연속으로 결석한 횟수]로 정의했다.
n번째 날에 개근상을 받을 수 있는 사람들의 조건은 다음과 같다.
1) 0번 지각 0번 연속 결석 -> dp[n][0][0]
2) 0번 지각 1번 연속 결석 -> dp[n][0][1]
3) 0번 지각 2번 연속 결석 -> dp[n][0][2]
4) 1번 지각 0번 연속 결석 -> dp[n][1][0]
5) 1번 지각 1번 연속 결석 -> dp[n][1][1]
6) 1번 지각 2번 연속 결석 -> dp[n][1][2]
n번째 날의 0번 지각 0번 연속 결석은 무조건 출석을 해야 도달할 수 있다.
1번, 2번 연속 결석한 사람도 출석을 하면 0번으로 초기화되므로
dp[n][0][0] = dp[n - 1][0][0] + dp[n - 1][0][1] + dp[n - 1][0][2]
0번 지각 1번 연속 결석은 무조건 결석을 해야한다. dp[n][0][1] = dp[n - 1][0][0]
0번 지각 2번 연속 결석도 마찬가지로 결석을 해야한다. dp[n][0][2] = dp[n - 1][0][1]
1번 지각 0번 결석은 지각해서 도달할 수도 있고, 출석해서 도달할 수도 있다.
dp[i][1][0] = dp[i - 1][0][0] + dp[i - 1][0][1] + dp[i - 1][0][2] + dp[i - 1][1][0] + dp[i - 1][1][1] + dp[i - 1][1][2]
dp[n][1][1], dp[n][1][2]는 dp[n][0][1], dp[n][0][2]와 비슷한 구조다.
'Algorithm > BAEKJOON' 카테고리의 다른 글
[BOJ] 11437번 LCA (C++) (0) | 2023.03.17 |
---|---|
[BOJ] 3584번 가장 가까운 공통 조상 (C++) (0) | 2023.03.16 |
[BOJ] 5567번 결혼식 (C++) (1) | 2022.11.12 |
[BOJ] 5502번 팰린드롬 (C++) (0) | 2022.11.11 |
[BOJ] 12015번 가장 긴 증가하는 부분 수열 2 (C++) (0) | 2022.11.07 |