DFS + Memoization, Short and Simple
First use DFS:\n\n\n    int ans = 0;\n    \n    public int dieSimulator(int n, int[] rollMax) {\n        dfs(n, rollMax, -1, 0);\n        return ans;\n    }\n  
First use DFS:\n\n```\n    int ans = 0;\n    \n    public int dieSimulator(int n, int[] rollMax) {\n        dfs(n, rollMax, -1, 0);\n        return ans;\n    }\n    \n\t// dieLeft : the number of dies\n\t// last : last number we rolled\n\t// curlen : current len of same number\n\t// This function trys to traval all the valid permutation\n    private void dfs(int dieLeft, int[] rollMax, int last, int curlen){\n        if(dieLeft == 0){\n            ans++;\n            return;\n        }\n        for(int i=0; i<6; i++){\n            if(i == last && curlen == rollMax[i]) continue;\n            dfs(dieLeft - 1, rollMax, i, i == last ? curlen + 1 : 1);\n        }\n    }\n```\n\nBut this will be TLE. So we add memoization:\n\n```\n    int[][][] dp = new int[5000][6][16];\n    final int M = 1000000007;\n    \n    public int dieSimulator(int n, int[] rollMax) {\n        return dfs(n, rollMax, -1, 0);\n    }\n    \n    private int dfs(int dieLeft, int[] rollMax, int last, int curlen){\n        if(dieLeft == 0) return 1;\n        if(last >= 0 && dp[dieLeft][last][curlen] > 0) return dp[dieLeft][last][curlen];\n        int ans = 0;\n        for(int i=0; i<6; i++){\n            if(i == last && curlen == rollMax[i]) continue;\n            ans = (ans + dfs(dieLeft - 1, rollMax, i, i == last ? curlen + 1 : 1)) % M;\n        }\n        if(last >= 0) dp[dieLeft][last][curlen] = ans;\n        return ans;\n    }\n```
[]