@LIUHUAN
2020-01-13T15:08:14.000000Z
字数 2524
阅读 1175
algorithm
const static int M = (int)(7 + 1e9);int numRollsToTarget(int d, int f, int target){return targetSum(d, f, target);}int targetSum(int d, int f, int target){if (d < 0 || target < 0)return 0;// base case,one way to roll diceif (target == 0 && d == 0)return 1;int c = 0;for (int i = 1; i <= f; i++){if (target == i && d == 1){c += 1;c %= M;} else if (target > i){int x = targetSum(d - 1, f, target - i);x %= M;c += x;c %= M;}elsebreak;}return c % M;}
map,也可以用数组,来缓存已经计算完的数据。对于已经获取的数据直接返回结果。map来保存,例如map["1->4"],表示的投掷结果。
const static int M = (int)(7 + 1e9);unordered_map<string, int> umap;int numRollsToTarget(int d, int f, int target){return targetSum(d, f, target);}int targetSum(int d, int f, int target){// 非法caseif (d < 0 || target < 0)return 0;// base caseif (target == 0 && d == 0)return 1;string k = to_string(d) + "-" + to_string(target);if (umap.find(k) != umap.end()) // 已经有结果的数据直接返回return umap[k];int c = 0;for (int i = 1; i <= f; i++){if (target == i && d == 1) // 一种合法情况{c += 1;c %= M;}else if (target > i) // 需要继续递归调用{int x = targetSum(d - 1, f, target - i);x %= M;c += x;c %= M;}else // 非法情况,target < i 说明无法继续掷骰子,来达到目标值break;}umap[k] = c % M;// 备忘录保存已经计算的结果return umap[k];}
const static int M = (int)(7 + 1e9);int numRollsToTarget(int d, int f, int target){if (target > d * f)return 0;if (target == d * f)return 1;vector<vector<int>> dp;dp.push_back(vector<int>(f + 1, 0));for (int i = 1; i <= d; i++){vector<int> r(i * f + 1, 0);dp.push_back(r);}for (int i = 1; i <= f; i++)dp[1][i] = 1;for (int i = 2; i <= d; i++){dp[i][i] = 1;int total = i * f;for (int j = i + 1; j <= total; j++){dp[i][j] = 0;for (int k = f; k >= 1; k--){int x = j - k;if (x > 0 && x < dp[i - 1].size()){dp[i][j] += dp[i - 1][j - k] % M;dp[i][j] %= M;}}if (j == target)break;}}return dp[d][target];// return targetSum(d, f, target);}