알고리즘, 코딩테스트
백준 9184번(신나는 함수 실행) c++ 풀이
552bin
2025. 3. 23. 22:11
https://www.acmicpc.net/problem/9184
주어진 재귀 함수를 보면,
특징 1) a, b, c 셋 중 하나가 0 이하일 때 1
특징 2) a, b, c 셋 중 하나가 20 초과일 때 w[20][20][20]
그리고 나머지 케이스에서 재귀 호출을 할 때
특징 3) 인수가 a, b, c, a - 1, b - 1, c - 1 에 속한다.
dp 테이블 채우기 좋자나..
특징 1로 베이스를 깔면 나머지 테이블은 채울 수 있다.
-50 ≤ a, b, c ≤ 50 라고 제한이 나와있긴 하지만 0 이하이면 0으로 치환시키고 20 초과이면 20으로 치환시키면 되니까
테이블은 인덱스 0부터 20까지만 필요하다.
이중 for문으로 베이스 깔아주고, 3중 for문 돌면서 나머지 테이블 채워준다.
답 출력할 때는 테이블에 저장된 값 활용할 수 있도록 a, b, c를 치환해주면 끝..
출력은 귀찮아서 printf 썼당
#include <iostream>
using namespace std;
int w[21][21][21];
void makeTable(){
for(int i=0; i<=20; i++){
for(int j=0; j<=20; j++){
w[0][i][j] = w[i][0][j] = w[i][j][0] = 1;
}
}
for(int i=1; i<=20; i++){
for(int j=1; j<=20; j++){
for(int k=1; k<=20; k++){
if(i < j && j < k){
w[i][j][k] = w[i][j][k - 1] + w[i][j - 1][k - 1] - w[i][j - 1][k];
}
else{
w[i][j][k] = w[i - 1][j][k] + w[i - 1][j - 1][k] + w[i - 1][j][k - 1] - w[i - 1][j - 1][k - 1];
}
}
}
}
return;
}
int ans(int a, int b, int c){
if(a <= 0 || b <= 0 || c <= 0){
a = b = c = 0;
}
if(a > 20 || b > 20 || c > 20){
a = b = c = 20;
}
return w[a][b][c];
}
int main(){
makeTable();
int a, b, c;
while(true){
cin >> a >> b >> c;
if(a == -1 && b == -1 && c == -1) break;
printf("w(%d, %d, %d) = %d\n", a, b, c, ans(a, b, c));
}
return 0;
}