题目出处点这里
思路:直接暴力递归肯定会TLE,可以建两个三维数组,一个把计算过的值存储起来,另一个存储相应位置有没有被计算过,如果被计算过直接返回即可,这样就减少了大量的重复计算
**
**
package reintroduction_recursion;
import java.util.Scanner;
public class P1464 {
static boolean[][][] isClac = new boolean[21][21][21];// 记录相应位置是否已经被计算过
static int[][][] res = new int[21][21][21];// 先定义一个三维数组记录结果
static int a = 0, b = 0, c = 0;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
a = sc.nextInt();
b = sc.nextInt();
c = sc.nextInt();
if (a == -1 && b == -1 && c == -1) {
break;
} else {
System.out.println("w(" + a + ", " + b + ", " + c + ") = " + w(a, b, c));
}
}
sc.close();
}
// 递归
public static int w(int a, int b, int c) {
if (a <= 0 || b <= 0 || c <= 0) {
//这里只能返回1,如果返回res[a][b][c],会出现索引为负的情况,会报错
return 1;
} else if (a > 20 || b > 20 || c > 20) {
//这里只能返回w(20, 20, 20),如果返回res[a][b][c]会数组越界
return w(20, 20, 20);
} else if (isClac[a][b][c]) {//体现记忆化搜索
return res[a][b][c];
} else if (a < b && b < c) {
//这里用res[a][b][c]存储,如果return 则会造成重复大量计算
res[a][b][c] = w(a, b, c - 1) + w(a, b - 1, c - 1) - w(a, b - 1, c);
} else {
//这里用res[a][b][c]存储,如果return 则会造成重复大量计算
res[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);
}
// 已经求出来了,在返回之前先将对应位置置为true,表示已经计算过,避免以后重复计算
isClac[a][b][c] = true;
return res[a][b][c];
}
}