题目链接:https://vjudge.net/problem/Gym-101190F
转自:https://blog.csdn.net/dormousenone/article/details/73699630
题意:1.对于一叠 n 张卡片,随机取前 k 张
2.若取到的 k 张的第一张为 W ,则 k 张卡片的状态全部翻转。
3.将 k 张卡片在桌面上展示
4.若一叠卡片仍有剩余,则继续上述操作
问最后桌面上为 W 的卡片的期望?
思路:首先计算对于第 i 张卡片,其为 k 张中的第一张的概率,依次为 1, 1/n , 1/(n−1) … (第一张概率必定是1,选取第一张的概率为1/n,这样第二张就成了第一张,概率等于1/n*1)
令 dp[i][0] 表示第 i 张卡片不翻的概率,dp[i][1] 表示第 i 张卡片翻转的概率,则 dp[i][0]+dp[i][1] = 1 。
令第 i 张为首张的概率为 p
若第 i 张为 W ,则其不翻的概率为 dp[i][0] = (1-p) * dp[i-1][0],因为这张W牌不翻面的概率等于它不是第一张并且上一张也不翻面的概率,下同。
若第 i 张为 C ,则其不翻的概率为 dp[i][0] = p + (1-p) * dp[i-1][0]
第 i 张翻转的概率为 dp[i][1] = 1 - dp[i][0]
统计每张最终为 W 的概率和即为问题期望
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
double dp[N][2];
int main()
{
freopen("foreign.in", "r", stdin);
freopen("foreign.out", "w", stdout);
string s;
double p,ans=0;
cin>>s;
int l=s.length();
if(s[0]=='W')
{
dp[0][0]=0;//不翻
dp[0][1]=1;//翻
}
else
{
dp[0][0]=1;
dp[0][1]=0;
}
for(int i=1; i<l; i++)
{
double p=(double)1/(l-i+1);
if(s[i]=='W')
{
dp[i][0]=(1-p)*dp[i-1][0];
dp[i][1]=p+(1-p)*dp[i-1][1];
}
else
{
dp[i][0]=p+(1-p)*dp[i-1][0];
dp[i][1]=(1-p)*dp[i-1][1];
}
if(s[i]=='W')
{
ans+=dp[i][0];
}
else
{
ans+=dp[i][1];
}
}
printf("%.10f",ans);
}