@LIUHUAN
2020-01-13T23:08:14.000000Z
字数 2524
阅读 941
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 dice
if (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;
}
else
break;
}
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)
{
// 非法case
if (d < 0 || target < 0)
return 0;
// base case
if (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);
}