题目
问,扔n次骰子,总点数在x次以上的概率是多少,n ≤ 24 、0 ≤ x < 150。
解题思路
用小数表示这题就很简单。换成用分数形式表示,只需要手写一下分数运算符即可。
代码
#include <bits/stdc++.h>
using namespace std;
struct node
{
long long a, b;
node operator*(const int &temp) const//乘法等价于乘分子
{
node res;
res.a = a * temp;
res.b = b;
return res;
}
node operator/(const int &temp) const//除法等价于乘分母
{
node res;
res.a = a;
res.b = b * temp;
return res;
}
node operator+(node &temp)
{
if (b == 0)
return node{temp.a, temp.b};
else if (temp.b == 0)
return node{a, b};
long long lcm = b / __gcd(b, temp.b) * temp.b;
a *= lcm / b;
temp.a *= lcm / temp.b;
node res;
res.a = a + temp.a;
res.b = lcm;
return res;
}
} dp[30][180]; //dp[i][j]表示扔i次 总和为j 的概率
int n, k;
void solve()
{
for (int i = 0; i < 30; i++)
for (int j = 0; j < 180; j++)
dp[i][j].a = dp[i][j].b = 0;
for (int i = 1; i <= 6; i++)
dp[1][i].a = 1, dp[1][i].b = 6;
for (int i = 2; i <= n; i++)
{
for (int j = i; j <= 6 * i; j++)
{
for (int k = 1; k <= 6; k++)
{
if (j - k >= 0)
{
//其实就一句
// dp[i][j] += dp[i - 1][j - k] * 1 / 6;
node temp;
temp = dp[i - 1][j - k];
temp = temp * 1;
temp = temp / 6;
dp[i][j] = dp[i][j] + temp;
}
}
}
}
node ans;
ans.a = ans.b = 0;
for (int i = k; i <= 6 * n; i++)
ans = ans + dp[n][i];
if (ans.b == 0)
cout << "0" << endl;
else
{
long long g = __gcd(ans.a, ans.b);
if (ans.a == ans.b)
{
cout << "1" << endl;
return;
}
cout << ans.a / g << '/' << ans.b / g << endl;
}
}
int main()
{
while (cin >> n >> k && (n + k))
solve();
return 0;
}