1155.Β Number of Dice Rolls With Target Sum

  • k개의 면을 κ°€μ§„ n개의 μ£Όμ‚¬μœ„λ₯Ό κ΅΄λ €μ„œ λ‚˜μ˜¨ 눈의 ν•©μœΌλ‘œ μ£Όμ–΄μ§„ 숫자 target을 λ§Œλ“€ 수 μžˆλŠ” 경우의 수λ₯Ό κ΅¬ν•œλ‹€.
  • μ£Όμ‚¬μœ„λ₯Ό ν•˜λ‚˜μ”© λ˜μ§€λ©΄μ„œ λ‚˜μ˜¨ μˆ«μžμ— 따라 target을 κ°μ†Œ μ‹œν‚€λ©΄μ„œ 결과적으둜 0이 될 λ•ŒκΉŒμ§€ 탐색을 μ§„ν–‰ν•œλ‹€.
    • n개의 μ£Όμ‚¬μœ„ 쀑 첫번째 μ£Όμ‚¬μœ„λ₯Ό λ˜μ‘Œμ„ λ•Œ 1 ~ kκΉŒμ§€μ˜ μˆ«μžκ°€ λ“±μž₯ν•˜λŠ” 경우의 μˆ˜κ°€ μ‘΄μž¬ν•˜λ©° 각각에 λŒ€ν•΄μ„œ λ‚˜λ¨Έμ§€ n - 1개의 μ£Όμ‚¬μœ„λ₯Ό λ˜μ Έμ„œ 눈의 합이 target - λ‚˜μ˜¨ 숫자 κ°€ λ˜λ„λ‘ ν•˜λ©΄ λœλ‹€.
    • 만일 target이 0보닀 μž‘μ€ 경우 잘λͺ»λœ 쑰합에 ν•΄λ‹Ήλ˜λ―€λ‘œ 경우의 μˆ˜λŠ” 0이닀.
    • λ§ˆμ°¬κ°€μ§€λ‘œ λ‚¨μ•„μžˆλŠ” μ£Όμ‚¬μœ„μ˜ μˆ˜κ°€ μ—†λŠ”λ° target이 0이 μ•„λ‹Œ κ²½μš°μ—λ„ 잘λͺ»λœ 쑰합에 ν•΄λ‹Ήλ˜λ―€λ‘œ 경우의 μˆ˜λŠ” 0이닀.
    • λ‚¨μ•„μžˆλŠ” μ£Όμ‚¬μœ„μ˜ μˆ˜λ„ μ—†κ³  target도 0이라면 λ‹€λ₯Έ 경우의 μˆ˜κ°€ μ—†μœΌλ―€λ‘œ κ²°κ³ΌλŠ” 1이 λœλ‹€.
  • νŠΉμ • 개수의 μ£Όμ‚¬μœ„λ‘œ νŠΉμ • target 숫자λ₯Ό λ§Œλ“œλŠ” 경우의 μˆ˜λŠ” 항상 λ™μΌν•˜λ―€λ‘œ memoization을 ν†΅ν•΄μ„œ 계산 속도λ₯Ό 높인닀.
    • 이 λ•Œ λ‘œμ§μ„ λ‹¨μˆœν™”ν•˜κΈ° μœ„ν•΄μ„œ μ£Όμ‚¬μœ„μ˜ μˆ˜κ°€ 0μ΄λ©΄μ„œ target 값이 0이 μ•„λ‹Œ κ²½μš°λŠ” 미리 값을 0으둜 μ΄ˆκΈ°ν™” ν•΄λ‘”λ‹€.
    • μ£Όμ‚¬μœ„μ˜ μˆ˜κ°€ 0μ΄λ©΄μ„œ target 값이 0이 μ•„λ‹Œ κ²½μš°λŠ” 미리 값을 1둜 μ΄ˆκΈ°ν™” ν•΄λ‘”λ‹€.
class Solution { final int MOD = 1_000_000_000 + 7; int traverse(int n, int k, int target, int[][] dp) { if (target < 0) return 0; if (dp[n][target] != -1) return dp[n][target]; int result = 0; for (int i = 1; i <= k; ++i) { result = (result + traverse(n - 1, k, target - i, dp)) % MOD; } return dp[n][target] = result; } public int numRollsToTarget(int n, int k, int target) { int[][] dp = new int[n + 1][target + 1]; for (int[] sub : dp) { Arrays.fill(sub, -1); } Arrays.fill(dp[0], 0); dp[0][0] = 1; return traverse(n, k, target, dp); } }