Use this to learn the idea, then write your own version.
1class Solution {2 public int getMaxGridHappiness(int m, int n, int introvertsCount, int extrovertsCount) {3 final int twoToThePowerOfN = (int) Math.pow(2, n);4 int[][][][][] mem = new int[m * n][twoToThePowerOfN][twoToThePowerOfN][introvertsCount + 1]5 [extrovertsCount + 1];6 return getMaxGridHappiness(m, n, 0, 0, 0, introvertsCount, extrovertsCount, mem);7 }8 9 10 11 12 13 14 15 16 17 private int getPlacementCost(int n, int i, int j, int inMask, int exMask, int diff) {18 int cost = 0;19 if (i > 0) {20 if (((1 << (n - 1)) & inMask) > 0)21 cost += diff - 30;22 if (((1 << (n - 1)) & exMask) > 0)23 cost += diff + 20;24 }25 if (j > 0) {26 if ((1 & inMask) > 0)27 cost += diff - 30;28 if ((1 & exMask) > 0)29 cost += diff + 20;30 }31 return cost;32 }33 34 private int getMaxGridHappiness(int m, int n, int pos, int inMask, int exMask, int inCount,35 int exCount, int[][][][][] mem) {36 37 38 39 40 41 final int i = pos / n;42 final int j = pos % n;43 if (i == m)44 return 0;45 if (mem[pos][inMask][exMask][inCount][exCount] > 0)46 return mem[pos][inMask][exMask][inCount][exCount];47 48 final int shiftedInMask = (inMask << 1) & ((1 << n) - 1);49 final int shiftedExMask = (exMask << 1) & ((1 << n) - 1);50 51 final int skip =52 getMaxGridHappiness(m, n, pos + 1, shiftedInMask, shiftedExMask, inCount, exCount, mem);53 final int placeIntrovert =54 inCount > 0 ? 120 + getPlacementCost(n, i, j, inMask, exMask, -30) +55 getMaxGridHappiness(m, n, pos + 1, shiftedInMask | 1, shiftedExMask,56 inCount - 1, exCount, mem)57 : Integer.MIN_VALUE;58 final int placeExtrovert =59 exCount > 0 ? 40 + getPlacementCost(n, i, j, inMask, exMask, 20) +60 getMaxGridHappiness(m, n, pos + 1, shiftedInMask, shiftedExMask | 1,61 inCount, exCount - 1, mem)62 : Integer.MIN_VALUE;63 return mem[pos][inMask][exMask][inCount][exCount] =64 Math.max(skip, Math.max(placeIntrovert, placeExtrovert));65 }66}67