Advertisement
goodwish

1223. Dice Roll Simulation

Nov 6th, 2019
136
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.45 KB | None | 0 0
  1. way 1, plain DP 的写法.
  2.  
  3. 今日所学:
  4. DP 递推等式的左边. 递推结果(即当前问题)的维度数值可以出现常数, 不一定非要是 i, j 循环变量.
  5. 当前问题的状态含有常数, 拆解为(多个)子问题.
  6.  
  7. 习得一个新模式, 即所谓的套路.
  8. i.e.: for pre in (1..6): f[i][j][1] += f[i-1][pre][k]
  9.  
  10. 状态定义为 f(k, index, i),代表数字 index 在前面出现 k 次时,掷到 i 次骰子会出现的序列个数.
  11.  
  12. 情况二:随机出的数字 curt_index 与 pre_index 不等,那么得到新的状态 f(1, curt_index, i), 当前问题, 状态含有常数 1, 连续一次.
  13. 情况三:随机出连续相同数字, curt_index == pre_index,还没到达上限,得到新状态 f(k+1, index, i)
  14.  
  15. class Solution:
  16.     def dieSimulator(self, n: int, rollMax: List[int]) -> int:
  17.         f = [[[0] * (16) for _ in range(6)] for _ in range(n + 1)]
  18.         MOD = 10**9 + 7
  19.         for j in range(6):
  20.             f[1][j][1] = 1
  21.        
  22.         for i in range(2, n + 1):
  23.             for j in range(6):
  24.                 for pre in range(6):
  25.                     for k in range(1, rollMax[pre] + 1):
  26.                         if pre != j:
  27.                             f[i][j][1] += f[i-1][pre][k]
  28.                         elif k < rollMax[j]:
  29.                             f[i][j][k + 1] += f[i-1][j][k]
  30.        
  31.         ans = 0
  32.         for j in range(6):
  33.             for k in range(1, rollMax[j] + 1):
  34.                 ans = (ans + f[n][j][k]) % MOD
  35.        
  36.         return ans
  37.        
  38. way 2, DFS + memo: top down approach.
  39.  
  40. class Solution:
  41.     def dieSimulator(self, n, rollMax):
  42.         memo = {}
  43.         self.MOD = 10**9 + 7
  44.         memo = [[[-1] * 16 for _ in range(6)] for _ in range(n + 1)]
  45.         ans = self.dfs(n, -1, 0, rollMax, memo)
  46.         return ans
  47.  
  48.     def dfs(self, n, j, k, M, memo):
  49.         if memo[n][j][k] != -1:
  50.             return memo[n][j][k]
  51.         if n == 0:
  52.             return 1
  53.         ans = 0
  54.         for pre in range(6):
  55.             if pre != j:
  56.                 ans += self.dfs(n - 1, pre, 1, M, memo)
  57.             elif k < M[j]:
  58.                 ans += self.dfs(n - 1, pre, k + 1, M, memo)
  59.         ans = ans % self.MOD
  60.         memo[n][j][k] = ans
  61.         return ans
  62.  
  63.  
  64. o = Solution()
  65.  
  66. n = 2; rollMax = [1,1,2,2,2,3] # 34
  67. # n = 3; rollMax = [1,1,1,2,2,3] # 181
  68. ans = o.dieSimulator(n, rollMax)
  69. print(ans)
  70. n = 4; rollMax = [2,1,1,3,3,2] # 1082
  71. ans = o.dieSimulator(n, rollMax)
  72. print(ans)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement