<p>You have <code>n</code> dice, and each dice has <code>k</code> faces numbered from <code>1</code> to <code>k</code>.</p>

<p>Given three integers <code>n</code>, <code>k</code>, and <code>target</code>, return <em>the number of possible ways (out of the </em><code>k<sup>n</sup></code><em> total ways) </em><em>to roll the dice, so the sum of the face-up numbers equals </em><code>target</code>. Since the answer may be too large, return it <strong>modulo</strong> <code>10<sup>9</sup> + 7</code>.</p>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>

<pre>
<strong>Input:</strong> n = 1, k = 6, target = 3
<strong>Output:</strong> 1
<strong>Explanation:</strong> You throw one die with 6 faces.
There is only one way to get a sum of 3.
</pre>

<p><strong class="example">Example 2:</strong></p>

<pre>
<strong>Input:</strong> n = 2, k = 6, target = 7
<strong>Output:</strong> 6
<strong>Explanation:</strong> You throw two dice, each with 6 faces.
There are 6 ways to get a sum of 7: 1+6, 2+5, 3+4, 4+3, 5+2, 6+1.
</pre>

<p><strong class="example">Example 3:</strong></p>

<pre>
<strong>Input:</strong> n = 30, k = 30, target = 500
<strong>Output:</strong> 222616187
<strong>Explanation:</strong> The answer must be returned modulo 10<sup>9</sup> + 7.
</pre>

<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
	<li><code>1 &lt;= n, k &lt;= 30</code></li>
	<li><code>1 &lt;= target &lt;= 1000</code></li>
</ul>

class Solution:
    def numRollsToTarget(self, d: int, n: int, s: int) -> int:
        # integer s given number d
        # s == d at least one sol 1 1 1 1 
        # s > d: b 1 1 1 1 1 1
        # b <= n
        # s = 100, d = 6 n = 5, 5 5 5 5 5

        memo = {}

        def solve(d, n, s):
            # check memo
            if (d, s) in memo:
                return memo[(d, s)]

            if d * n < s:
                memo[(d, s)] = 0
                return 0 # impossible case
            elif d > s:
                memo[(d, s)] = 0
                return 0
            
            if d == 1 and s >= 1 and s <= n:
                memo[(d, s)] = 1
                return 1

            # doable
            # if fix the first die tobe m
            # s = s - m; d = d - 1
            sol = 0
            for m in range(1, n+1):
                sol += solve(d-1, n, s-m)
                sol %= 1000000007

            # O(n ^ d)
            # first roll 1, then roll out 2
            # first roll 2 then roll 1
            # the number of dice we left and the number we are still waiting to add -> unique subproblem
            # map: (#dice, s) -> # permutations

            memo[(d, s)] = sol
            return sol
        return solve(d,n,s)

18800