[关闭]
@LIUHUAN 2020-01-13T23:08:14.000000Z 字数 2524 阅读 966

掷骰子结果之和等于特定数的方法从递归到结束

algorithm


掷骰子结果之和等于特定数的方法

方法一:递归

  1. const static int M = (int)(7 + 1e9);
  2. int numRollsToTarget(int d, int f, int target)
  3. {
  4. return targetSum(d, f, target);
  5. }
  6. int targetSum(int d, int f, int target)
  7. {
  8. if (d < 0 || target < 0)
  9. return 0;
  10. // base case,one way to roll dice
  11. if (target == 0 && d == 0)
  12. return 1;
  13. int c = 0;
  14. for (int i = 1; i <= f; i++)
  15. {
  16. if (target == i && d == 1)
  17. {
  18. c += 1;
  19. c %= M;
  20. } else if (target > i)
  21. {
  22. int x = targetSum(d - 1, f, target - i);
  23. x %= M;
  24. c += x;
  25. c %= M;
  26. }
  27. else
  28. break;
  29. }
  30. return c % M;
  31. }

方法二:转化为备忘录递归

  1. const static int M = (int)(7 + 1e9);
  2. unordered_map<string, int> umap;
  3. int numRollsToTarget(int d, int f, int target)
  4. {
  5. return targetSum(d, f, target);
  6. }
  7. int targetSum(int d, int f, int target)
  8. {
  9. // 非法case
  10. if (d < 0 || target < 0)
  11. return 0;
  12. // base case
  13. if (target == 0 && d == 0)
  14. return 1;
  15. string k = to_string(d) + "-" + to_string(target);
  16. if (umap.find(k) != umap.end()) // 已经有结果的数据直接返回
  17. return umap[k];
  18. int c = 0;
  19. for (int i = 1; i <= f; i++)
  20. {
  21. if (target == i && d == 1) // 一种合法情况
  22. {
  23. c += 1;
  24. c %= M;
  25. }else if (target > i) // 需要继续递归调用
  26. {
  27. int x = targetSum(d - 1, f, target - i);
  28. x %= M;
  29. c += x;
  30. c %= M;
  31. }
  32. else // 非法情况,target < i 说明无法继续掷骰子,来达到目标值
  33. break;
  34. }
  35. umap[k] = c % M;// 备忘录保存已经计算的结果
  36. return umap[k];
  37. }

方法三:掷骰子结果之和等于特定数的方法(转化为迭代计算)

  1. const static int M = (int)(7 + 1e9);
  2. int numRollsToTarget(int d, int f, int target)
  3. {
  4. if (target > d * f)
  5. return 0;
  6. if (target == d * f)
  7. return 1;
  8. vector<vector<int>> dp;
  9. dp.push_back(vector<int>(f + 1, 0));
  10. for (int i = 1; i <= d; i++)
  11. {
  12. vector<int> r(i * f + 1, 0);
  13. dp.push_back(r);
  14. }
  15. for (int i = 1; i <= f; i++)
  16. dp[1][i] = 1;
  17. for (int i = 2; i <= d; i++)
  18. {
  19. dp[i][i] = 1;
  20. int total = i * f;
  21. for (int j = i + 1; j <= total; j++)
  22. {
  23. dp[i][j] = 0;
  24. for (int k = f; k >= 1; k--)
  25. {
  26. int x = j - k;
  27. if (x > 0 && x < dp[i - 1].size())
  28. {
  29. dp[i][j] += dp[i - 1][j - k] % M;
  30. dp[i][j] %= M;
  31. }
  32. }
  33. if (j == target)
  34. break;
  35. }
  36. }
  37. return dp[d][target];
  38. // return targetSum(d, f, target);
  39. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注