典型的记忆化递归问题。

这类问题的记忆主要是利用数组记忆。那么已经计算过的值就能够直接返回。不须要进一步递归了。

注意:下标越界。递归顺序不能错,及时推断是否已经计算过值了,不要多递归。

或者直接使用动态规划法填好表也是能够的。


#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;
}