Java || Memoization || DP
```\nclass Solution {\n    int[][][] dp = new int[5000][7][16];\n    public int dieSimulator(int n, int[] rollMax) {\n        //  no number is chosen initially 
```\nclass Solution {\n    int[][][] dp = new int[5000][7][16];\n    public int dieSimulator(int n, int[] rollMax) {\n        //  no number is chosen initially and total remaining length is "n" and cons is 0 too.\n\t\treturn helper(n, rollMax, 0, 0);\n    }\n    \n    public int helper(int n, int[] a, int prev, int cons) {\n        if (n == 0) {\n            //  length is exhausted\n            return 1;\n        }\n        int answer = 0;\n        //  dp[n][prev][cons] -> total number of distinct subsequences of length n ending at the \n        //  roll "prev" and occuring "cons" times.\n        if (dp[n][prev][cons] != 0) {\n            return dp[n][prev][cons];\n        }\n        for (int i = 0; i < 6; i++) {\n            if ((i + 1) == prev) {\n                //  if the current number is same as the previous number then check the\n                //  consecutive occurence of this same number if it is less than than \n                //  the limit then we can use this again and increase the consecutive \n                //  count else we can not use this number again \n                if (a[i] > cons) {\n                    answer = (answer + helper(n-1, a, prev, cons + 1)) % 1_000_000_007;\n                }\n            } else {\n                //  this number was different than the previous number\n                //  so we can use it because 1 <= rollMax[i] <= 15\n                answer = (answer + helper(n-1, a, i+1, 1)) % 1_000_000_007;\n            }\n        }\n        return dp[n][prev][cons] = answer;\n    }\n}
[]