1 条题解
-
0
解题思路
- 函数
f
的功能:f
函数接受三个整数参数c
、n
和m
。- 首先检查
mem[n][m]
是否已经计算过(即是否不等于-1
),如果是则直接返回mem[n][m]
,实现记忆化搜索。 - 检查
n
和m
的奇偶性是否不同,以及m
是否大于c
或m
是否大于n
,如果满足这些条件则返回0
。 - 如果
n
为1
且m
为1
,则返回1
。 - 分别计算
a1
和a2
:- 如果
m > 0
,则a1 = f(c, n - 1, m - 1) * (c - m + 1) / c
。 - 如果
m < c
,则a2 = f(c, n - 1, m + 1) * (m + 1) / c
。
- 如果
- 将
a1 + a2
的结果存入mem[n][m]
并返回。
- 主函数
main
的处理流程:- 使用
while
循环持续读取输入的c
。 - 如果
c
为0
,则跳出循环。 - 读取
n
和m
。 - 检查
m
是否大于c
、n
和m
的奇偶性是否不同以及m
是否大于n
,如果满足这些条件则输出0.000
。 - 如果
n
为0
且m
为0
,则输出1.000
。 - 当
n >= 10000
时,对n
进行调整(n = 9998 + n % 2
)。 - 初始化
mem
数组,将所有元素设为-1
。 - 调用
f(c, n, m)
计算概率值answer
,并按照固定格式(保留三位小数)输出answer
。
- 使用
#include <iostream> #include <iomanip> using namespace std; double mem[10000][103]; double f(int c, int n, int m) { if (mem[n][m] != -1) return mem[n][m]; if (n%2 != m%2 || m > c || m > n) return 0; if (n == 1 && m == 1) return 1; double a1 = 0, a2 = 0; if (m > 0) { a1 = f(c, n-1, m-1)*(c-m+1)/c; } if (m < c) { a2 = f(c, n-1, m+1)*(m+1)/c; } mem[n][m] = a1+a2; return mem[n][m]; } int main() { int c, n, m; while (cin >> c) { if (c == 0) break; cin >> n >> m; int i, j; if (m > c || (n%2) != (m%2) || m > n) cout << "0.000" << endl; else if (n == 0 && m == 0) cout << "1.000" << endl; else { if (n >= 10000) n = 9998+n%2; for (i = 0; i < 10000; i++) for (j = 0; j <= c; j++) mem[i][j] = -1; double answer = f(c, n, m); cout << setiosflags(ios::fixed) << setprecision(3) << answer << endl; } } return 0; }
- 函数
- 1
信息
- ID
- 323
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者