比起dp[21][21][21]来少存了5000个数,不知道为啥还是会爆内存
import java.util.Scanner;
public class Main {
//存变化的2470个数字
static int[] newDp = new int[2491];
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = 1;
for (int i = 0; i <= 20; i++) {
newDp[i] = n;
n *= 2;
}
w();
int[] nums = new int[3];
String[] arr;
while (true) {
//字符串判断
arr = sc.nextLine().split(" ");
if (arr[0].equals("-1") && arr[1].equals("-1") && arr[2].equals("-1")) {
break;
}
//判断长度大的数字是正数还是负数,并且将字符串中的数字放到整数数组中
for (int i = 0; i < arr.length; i++) {
if (arr[i].length() > 2) {
if (arr[i].charAt(0) == '-') {
nums[i] = -1;
} else {
nums[i] = 21;
}
} else {
nums[i] = Integer.parseInt(arr[i]);
}
}
//判断整数数组是否满足规则一
for (int i = 0; i < nums.length; i++) {
if (nums[i] <= 0) {
nums[0] = nums[1] = nums[2] = 0;
break;
}
}
//判断是否符合规则二
for (int i = 0; i < nums.length; i++) {
if (nums[i] > 20) {
nums[0] = nums[1] = nums[2] = 20;
}
}
System.out.println("w(" + arr[0] + ", " + arr[1] + ", " + arr[2] + ")" + " = " + newDp[getSub(nums[0], nums[1], nums[2])]);
}
}
private static int getSub(int a, int b, int c) {
if (a > b && a > c && b != 0 && c != 0) {
int num = 20;
for (int i = 1; i < a - 1; i++) {
num += i * i;
}
num += (b - 1) * (a - 1) + c;
return num;
} else if (b == 0 || c == 0) {
return 0;
} else {
return a;
}
}
private static void w() {
for (int i = 21; i < newDp.length; i++) {
for (int a = 2; a <= 20; a++) {
for (int b = 1; b < a; b++) {
for (int c = 1; c < a; c++) {
if (getSub(a, b, c) == i) {
newDp[i] = newDp[getSub(a - 1, b, c)] + newDp[getSub(a - 1, b - 1, c)] + newDp[getSub(a - 1, b, c - 1)] - newDp[getSub(a - 1, b - 1, c - 1)];
}
}
}
}
}
}
}