class Solution {
  private static final long MOD = 1000000007;

  public int numRollsToTarget(int n, int k, int target) {
    // out of bounds
    if (n > target || target > n * k) {
      return 0;
    }

    long[][] dp = new long[n + 1][target + 1];
    dp[0][0] = 1;

    for (int toss = 1; toss <= n; ++toss) {
      for (int sumIdx = toss, maxSumIdx = Math.min(target, toss * k);
          sumIdx <= maxSumIdx;
          ++sumIdx) {
        for (int f = 1; f <= Math.min(k, sumIdx); ++f) {
          dp[toss][sumIdx] = (dp[toss][sumIdx] + dp[toss - 1][sumIdx - f]) % MOD;
        }
      }
    }

    return (int) dp[n][target];
  }
}