내 상상(?)속의 DP는 규칙을 냅다 찾아 점화식을 만들어 답을 먼저 구해놓고,
입력을 받아 바로 답을 출력하는 그런 느낌의 풀이법으로 알고 있었다.
뒷부분은 얼추 맞게 생각했는데 규칙을 찾아야된다는 생각으로
냅다 w(20, 20, 20)을 풀어헤치기 시작했다.
오 완전 헛짓거리였고 그냥 문제를 곧이 곧대로 받아들이면 된다.
주어진 함수대로, 0과 20을 경계로 잡아 3차원 배열을 생성한 뒤
어느 하나가 0일 때
는 1을 먼저 채워주고,
a < b < c일 때
와 그 외의 경우
에 주어진 식대로 답 배열을 채운다.
어느 하나라도 20을 넘을 때
는 입력 부분에서 걸러주면 된다.
#include <iostream>
using namespace std;
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
int w[21][21][21] = { 0, };
for (int i = 0; i <= 20; i++) {
for (int j = 0; j <= 20; j++) {
w[0][i][j] = 1;
w[i][0][j] = 1;
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];
}
}
}
int a, b, c, ans;
while (1) {
cin >> a >> b >> c;
if (a == -1 && b == -1 && c == -1) break;
if (a <= 0 || b <= 0 || c <= 0) ans = 1;
else if (a > 20 || b > 20 || c > 20) ans = w[20][20][20];
else ans = w[a][b][c];
cout << "w(" << a << ", " << b << ", " << c << ") = " << ans << "\n";
}
return 0;
}
알고리즘을 풀 때 3중 for문
을 작성하는 것은
마치 죄를 짓는 것 같은 기분이 드는데
시원하게 풀리자 엄청난 쾌감