C++, DP O(n) time O(1) space ping-pong buffer with explanation
The intuition comes from the constraint. Since the constraint is about the consecutive number, in each throw, track the amount of sequences for every valid cons
The intuition comes from the constraint. Since the constraint is about the consecutive number, in each throw, track the amount of sequences for every valid consecutive number of every dice.\n\nLet **dp[n][i][j]** stands for number of sequence ending with **dice number=i** and dice number i consecutively appears **exactly j time(s) in the last j throw(s)**, and n for throw count. For example, dp[n][1][3] stands for number of sequences in form of "a b c d e A 111", where "A" could be any dice number except 1 but "a b c d e" could be any dice number including 1 in some throw n.\n\n**dp[n][i][j] = dp[n-1][i][j-1]** for j >= 2.\n\nWhile j equals to 1, this means current throw will make exactly 1 occurance and its possible prefix sequences come from all of the other dice numbers except the one which is going to show up, depicted as following equation.\n\n**dp[n][i][1] = sum(dp[n-1][p][q], p = 1...6 && p != i, q = 1...15)** for j = 1.\n\nExample:\nn = 3, rollMax = [1,1,1,2,2,3]\n\n```\ndp[i][j]\n                throw #1          throw #2          throw #3\ndice #1         [0, 1]            [0, 5]            [0, 28]\ndice #2         [0, 1]            [0, 5]            [0, 28]\ndice #3         [0, 1]            [0, 5]            [0, 28]\ndice #4         [0, 1]            [0, 5, 1]         [0, 27, 5]\ndice #5         [0, 1]            [0, 5, 1]         [0, 27, 5]\ndice #6         [0, 1]            [0, 5, 1]         [0, 27, 5, 1]\nsum             6                 33                181 \n```\n\nSince dp[n] only dependes on dp[n-1], ping-pong buffer is enough.\nFor coding convention, index j is in the range of 0 - 16. dp[i][0] is undefined; dp[i][1...15] stands for consecutive occurance because n <= 15; dp[i][16] stands for sum(dp[i][1...15]).\n\n```\n#define MMAX (1000000007LL)\n\nclass Solution {\npublic:  \n    int dieSimulator(int n, vector<int>& rollMax) {\n        vector<vector<long long>> cur(6, vector<long long>(17, 0LL));\n        vector<vector<long long>> prv(6, vector<long long>(17, 0LL));\n        vector<vector<long long>> t;\n        long long ret;\n        \n\t\tif (n <= 0) return 0;\n\t\t\n        for (int d = 0; d < 6; d++) {\n            cur[d][1] = 1;\n            cur[d][16] = 1; \n        }\n        \n        for (int i = 1; i < n; i++) {\n            // ping-pong\n            t = cur; cur = prv; prv = t;\n            \n            for (int d = 0; d < 6; d++) {\n                int lstidx = rollMax[d]; // last index \n\n                cur[d][1] = 0;\n                for (int d2 = 0; d2 < 6; d2++) {\n                    if (d == d2)\n                        continue;\n                    \n                    cur[d][1] += prv[d2][16];\n                    cur[d][1] %= MMAX;\n                }\n                memcpy(&(cur[d][2]), &(prv[d][1]), sizeof(long long) * (rollMax[d] -1));\n                \n                // index 16 = sum\n                if (prv[d][16] < prv[d][lstidx])\n                    prv[d][16] += MMAX;\n                cur[d][16] = prv[d][16] - prv[d][lstidx];\n                \n                cur[d][16] += cur[d][1];\n                cur[d][16] %= MMAX;\n            }\n        }\n  \n        ret = 0LL;\n        for (int d = 0; d < 6; d++) {\n            ret += cur[d][16];\n            ret %= MMAX;\n        }\n        return (int)ret;\n    }\n};\n```
[]