随机的机器人
有一条无限长的纸带,分割成一系列的格子,最开始所有格子初始是白色。现在在一个格子上放上一个萌萌的机器人(放上的这个格子也会被染红),机器人一旦走到某个格子上,就会把这个格子涂成红色。现在给出一个整数n,机器人现在会在纸带上走n步。每一步,机器人都会向左或者向右走一个格子,两种情况概率相等。机器人做出的所有随机选择都是独立的。现在需要计算出最后纸带上红色格子的期望值。
输入描述:
输入包括一个整数n(0 ≤ n ≤ 500),即机器人行走的步数。输出描述:
输出一个实数,表示红色格子的期望个数,保留一位小数。输入例子:
4输出例子:
3.4
分析:概率期望问题感觉没法下手,不知道动态规划还能这么玩
dp[i][j][k]表示走了i步后,纸带上有
则dp[i][j][k]的概率会转移到dp[i+1][][]的两个位置上:
机器人位于最左边红格子:
dp[i][j][1]/2 的概率会转移到dp[i+1][j+1][1]
dp[i][j][1]/2 的概率会转移到dp[i+1][j][2]机器人位于最右边红格子:
dp[i][j][j]/2 的概率会转移到dp[i+1][j+1][j+1]
dp[i][j][j]/2 的概率会转移到dp[i+1][j][j−1]其余情况:
dp[i][j][k]/2的概率会转移到dp[i+1][j][k+1]
dp[i][j][k]/2的概率会转移到dp[i+1][j][k−1]
最终走完n步后,加权求和即为期望
注意:数组如果过大,直接在栈分配 牛客网会提示段错误
#include <vector>
#include <iostream>
#include <string>
#include <numeric>
#include <iomanip>
using namespace std;
#define debug_
vector<vector<vector<double>>> dp;
vector<double> vec;
vector<vector<double>> vec_2;
//dp[2][503][503]
double func(int n)
{
vec.resize(503);
vec_2.resize(503, vec);
dp.resize(2, vec_2);
dp[0][1][1] = 1;
int prestep, curstep;
for (auto i = 1; i <= n; ++i)
{
prestep = (i - 1) % 2;
curstep = i % 2;
for (auto j = 0; j <= n + 1; ++j)
for (auto k = 0; k <= n + 1; ++k)
dp[curstep][j][k] = 0;
for (auto j = 0; j <= n + 1; ++j)
for (auto k = 1; k <= n + 1; ++k)
{
if (k == 1)//向左
{
dp[curstep][j + 1][k] += dp[prestep][j][k] / 2.;
}
else
{
dp[curstep][j][k - 1] += dp[prestep][j][k] / 2.;
}
if (k == j)//向右
{
dp[curstep][j + 1][k + 1] += dp[prestep][j][k] / 2.;
}
else
{
dp[curstep][j][k + 1] += dp[prestep][j][k] / 2.;
}
}
}
curstep = n % 2;
double result(0);
for (auto j = 0; j <= n + 1; ++j)
{
double a(0);
for (auto i = 0; i < 501; ++i)
{
a += dp[curstep][j][i];
}
result += (double)j*accumulate(dp[curstep][j].begin(), dp[curstep][j].end(), 0.);
}
return result;
}
int main()
{
int n;
#ifdef debug_
n = 500;
#else
cin >> n;
#endif
cout << fixed << setprecision(1)<< func(n);
return 0;
}