一个有6个面的骰子,每个面的点数是1,2,3,4,5,6,获得每个面的概率是一样的,问投掷n次之后的最大期望值是多少,怎么求
时间: 2024-04-23 14:24:48 浏览: 313
假设投掷 n 次骰子,我们用 f(i, j) 表示前 i 次投掷,点数总和为 j 的最大期望值。则我们有以下状态转移方程:
f(i, j) = max(f(i, j), f(i-1, j-k) + k/n) (1 ≤ k ≤ 6)
这个式子的含义是,在前 i-1 次投掷中,点数总和为 j-k 的最大期望值为 f(i-1, j-k),那么在第 i 次投掷中,我们可以得到 k 的点数,所以点数总和为 j 的最大期望值就是 f(i-1, j-k) + k/n,我们需要取其中的最大值。
最终的答案就是 f(n, n)。因为投掷 n 次骰子,最大点数总和不会超过 n,所以我们只需要求出 f(n, n) 即可。
时间复杂度为 O(n^3),可以通过此题。
参考代码如下:
相关问题
用python写一下:我们知道一个骰子有 6 个面,分别刻了 1 到 6 个点。下面给你 6 个骰子的初始状态,即它们朝上一面的点数,让你一把抓起摇出另一套结果。假设你摇骰子的手段特别精妙,每次摇出的结果都满足以下两个条件: 1、每个骰子摇出的点数都跟它之前任何一次出现的点数不同; 2、在满足条件 1 的前提下,每次都能让每个骰子得到可能得到的最大点数。 那么你应该可以预知自己第 n 次(1≤n≤5)摇出的结果。 输入格式: 输入第一行给出 6 个骰子的初始点数,即 [1,6] 之间的整数,数字间以空格分隔;第二行给出摇的次数 n(1≤n≤5)。 输出格式: 在一行中顺序列出第 n 次摇出的每个骰子的点数。数字间必须以 1 个空格分隔,行首位不得有多余空格。 输入样例: 3 6 5 4 1 4 3 输出样例: 4 3 3 3 4 3 样例解释: 这 3 次摇出的结果依次为: 6 5 6 6 6 6 5 4 4 5 5 5 4 3 3 3 4 3
```python
# 判断是否可以选择最大值
def can_choose_max(dice, cur):
for i in range(6):
if dice[i] == cur:
return False
if cur == 6 or cur == 1:
return True
if cur + 1 <= 6 and cur + 1 not in dice:
return True
if cur - 1 >= 1 and cur - 1 not in dice:
return True
return False
# 模拟摇骰子
def roll_dice(dice, n):
for i in range(n):
res = []
for j in range(6):
cur = dice[j]
if can_choose_max(dice, cur):
# 如果可以选择最大值,就选最大值
if cur + 1 <= 6 and cur + 1 not in dice:
res.append(cur + 1)
elif cur - 1 >= 1 and cur - 1 not in dice:
res.append(cur - 1)
else:
res.append(cur)
else:
# 否则只能选择其他值
for k in range(1, 7):
if k != cur and k not in dice:
res.append(k)
break
dice = res
return dice
# 主程序
if __name__ == '__main__':
dice = list(map(int, input().split()))
n = int(input())
res = roll_dice(dice, n)
print(*res)
```
思路:
- 首先实现一个函数 `can_choose_max`,用于判断当前骰子是否可以选择最大值。如果当前骰子已经出现过这个数,或者这个数左右两边都已经出现过了,那么就不能选择最大值。
- 然后实现一个函数 `roll_dice`,用于模拟摇骰子的过程。每次都遍历每一个骰子,判断是否可以选择最大值,如果可以就选最大值,否则只能选择其他值。
- 最后在主程序中读入初始状态和摇骰子次数,调用 `roll_dice` 函数输出结果即可。
们知道一个骰子有 6 个面,分别刻了 1 到 6 个点。下面给你 6 个骰子的初始状态,即它们朝上一面的点数,让你一把抓起摇出另一套结果。假设你摇骰子的手段特别精妙,每次摇出的结果都满足以下两个条件: 1、每个骰子摇出的点数都跟它之前任何一次出现的点数不同; 2、在满足条件 1 的前提下,每次都能让每个骰子得到可能得到的最大点数。 那么你应该可以预知自己第 n 次(1≤n≤5)摇出的结果。 输入格式: 输入第一行给出 6 个骰子的初始点数,即 [1,6] 之间的整数,数字间以空格分隔;第二行给出摇的次数 n(1≤n≤5)。 输出格式: 在一行中顺序列出第 n 次摇出的每个骰子的点数。数字间必须以 1 个空格分隔,行首位不得有多余空格。c++完整代码
```cpp
#include <iostream>
using namespace std;
const int N = 6;
int dice[N], ans[N];
bool st[N];
// 计算每个骰子可能的最大点数
int get_max(int x)
{
int res = 0;
for (int i = 1; i <= 6; i++)
if (i != x && i != 7 - x)
res = max(res, i);
return res;
}
// 模拟摇骰子过程
void roll(int n)
{
for (int i = 0; i < N; i++)
ans[i] = dice[i];
for (int i = 0; i < N; i++)
{
if (!st[i]) // 如果这个骰子没有被选过
{
int max_num = get_max(ans[i]); // 计算最大点数
for (int j = 0; j < N; j++)
if (j != i && ans[j] == max_num) // 找到与这个骰子不同的最大点数的骰子
swap(ans[i], ans[j]); // 交换
}
}
for (int i = 0; i < N; i++)
dice[i] = ans[i];
if (n == 1)
{
for (int i = 0; i < N; i++)
cout << dice[i] << ' ';
cout << endl;
return;
}
for (int i = 0; i < N; i++)
{
if (!st[i])
{
st[i] = true;
roll(n - 1);
st[i] = false;
}
}
}
int main()
{
for (int i = 0; i < N; i++)
cin >> dice[i];
int n;
cin >> n;
roll(n);
return 0;
}
```
阅读全文