典型的记忆化递归问题。
这类问题的记忆主要是利用数组记忆,那么已经计算过的值就可以直接返回,不需要进一步递归了。
注意:下标越界,递归顺序不能错,及时判断是否已经计算过值了,不要多递归。
或者直接使用动态规划法填好表也是可以的。
#include <stdio.h>
#include <limits.h>
const int MAX_N = 21;
int W[MAX_N][MAX_N][MAX_N];
int getValue(int a, int b, int c)
{
if (a <= 0 || b <= 0 || c <= 0) return W[0][0][0] = 1;
if (a >= MAX_N || b >= MAX_N || c >= MAX_N)
return getValue(MAX_N-1, MAX_N-1, MAX_N-1);
if (W[a][b][c]) return W[a][b][c];
if (a < b && b < c)
{
W[a][b-1][c-1] = getValue(a, b-1, c-1);
W[a][b][c-1] = getValue(a, b, c-1);
W[a][b-1][c] = getValue(a, b-1, c);
return W[a][b][c] = W[a][b][c-1] + W[a][b-1][c-1] - W[a][b-1][c];
}
W[a-1][b-1][c-1] = getValue(a-1, b-1, c-1);
W[a-1][b-1][c] = getValue(a-1, b-1, c);
W[a-1][b][c-1] = getValue(a-1, b, c-1);
W[a-1][b][c] = getValue(a-1, b, c);
return W[a][b][c] = W[a-1][b][c] + W[a-1][b-1][c]
+ W[a-1][b][c-1] - W[a-1][b-1][c-1];
}
int main()
{
int a, b, c;
while (~scanf("%d %d %d", &a, &b, &c)&& !(a == -1 && b == -1 && c == -1))
{
printf("w(%d, %d, %d) = %d\n", a, b, c, getValue(a, b, c));
}
return 0;
}