洛谷P1464 Java解法

题目出处点这里
洛谷P1464 Java解法_第1张图片
思路:直接暴力递归肯定会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];
	}
}

你可能感兴趣的:(洛谷)