package hackerrank;

import java.util.Scanner;

/**
 * https://www.hackerrank.com/challenges/lego-blocks
 */
public class LegoBlocks {
    private static long legoBlocks(int n, int m) {
        long total = (long) Math.pow(combinations(m), n);
        System.out.println("total: " + total);
        for (int i = 1; i <= m - 1; i++) {
            long substract = (long) Math.pow(combinations(i), n);
            System.out.println("substract: " + substract);
            total -= substract;
        }
        // TODO
        return total;
    }

    private static long combinations(int width) {
        if (width < 0) {
            return 0;
        }
        if (width == 0) {
            return 1;
        }
        long max = 0;
        for (int i = 1; i <= 4; i++) {
            max += combinations(width - i);
        }
        return max;
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int testCases = in.nextInt();
        for (int t = 0; t < testCases; t++) {
            int n = in.nextInt();
            int m = in.nextInt();
            System.out.println(legoBlocks(n, m));
        }
    }
}

@@ -14,16 +14,64 @@
 rrank;%0A%0A
+import java.util.HashMap;%0Aimport java.util.Map;%0A
 import j
@@ -223,24 +223,75 @@
 n, int m) %7B%0A
+        Map%3CInteger, Long%3E memo = new HashMap%3C%3E();%0A
         long
@@ -319,22 +319,25 @@
 pow(
-combinations(m
+allBlocks(m, memo
 ), n
@@ -446,25 +446,17 @@
    long 
-substract
+a
  = (long
@@ -470,29 +470,144 @@
 pow(
-combinations(i
+allBlocks(i, memo), n);%0A//            System.out.println(%22a: %22 + a);%0A            long b = (long) Math.pow(allBlocks(m - i, memo
 ), n);%0A
+//
     
@@ -634,25 +634,138 @@
 rintln(%22
-substract
+b: %22 + b);%0A            long substract = a * b;%0A//            System.out.println(%22substract (%22 + i + %22 and %22 + (m - i) + %22)
 : %22 + su
@@ -889,30 +889,52 @@
 ong 
-combinations(int width
+allBlocks(int width, Map%3CInteger, Long%3E memo
 ) %7B%0A
@@ -1040,32 +1040,117 @@
 rn 1;%0A        %7D%0A
+        if (memo.containsKey(width)) %7B%0A            return memo.get(width);%0A        %7D%0A
         long max
@@ -1217,19 +1217,16 @@
  += 
-combination
+allBlock
 s(wi
@@ -1232,16 +1232,22 @@
 idth - i
+, memo
 );%0A     
@@ -1243,32 +1243,62 @@
 emo);%0A        %7D%0A
+        memo.put(width, max);%0A
         return m

Update Lego Blocks