题目描述
有 n 个人排成一排,一开始全部面向前方,然后随机朝左或是朝右转。
然后我们不断审查这个队列,每次选择两个面对面的相邻的人,将他们从队列中取出。
例如(>
表示向右,<
表示向左):
- 队列
>>><<<
的消除过程为,>>><<<
到>><<
到><
到空队列(每次去除一对)。 - 队列
>><><<<>
的消除过程为,>><><<<>
到>><<<>
到><<>
到<>
(每次去除一对)。
求最后期望能够剩下多少人。
输入格式
一行一个正整数 n 。
输出格式
一行一个实数,表示期望剩下的人数,四舍五入保留三位小数。
样例
样例输入
10
样例输出
4.168
数据范围与提示
1≤n≤2000
f[i][j]表示前i个人中向右看并且没有被消除的人数的概率
如果第i+1个人是向右,f[i+1][j+1]=f[i][j]/2;
如果第i+1个人是向左,f[i+1][j-1]=f[i][j]/2;
这是只考虑了向右看的情况,所以最终结果*2包含向左看
#include <iostream>
#include <cstdio>
#include <cmath>
#include <queue>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int N = 1e5+10;
const int mod = N;
typedef long long LL;
double dp[2010][2010];
int main()
{
memset(dp,0,sizeof(dp));
int n;
scanf("%d", &n);
dp[0][0]=1;
for(int i=0;i<=n;i++)
{
for(int j=0;j<=i;j++)
{
if(j) dp[i+1][j+1]+=dp[i][j]*0.5,dp[i+1][j-1]+=dp[i][j]*0.5;
else dp[i+1][1]+=dp[i][j]*0.5,dp[i+1][0]=dp[i][j]*0.5;
}
}
double ans=0;
for(int i=1;i<=n;i++)
{
ans+=i*dp[n][i];
}
printf("%.3f\n",ans*2);
return 0;
}