题意:给定n表示有n个格子,下面每个格子为O的概率是多少。对于一段连续 x 个O的价值就是 x^2 ;求获得的价值的期望是多少。
思路:n^2=n×(n-1)+n,设ai为第i段连续O的长度,∑ai^2 = ∑[ ai+ ai*(ai-1) ] = ∑ ai*(ai-1) + ∑ai = ∑ C(ai, 2)*2 + ∑ai,那么问题可以转
化为求长度大于1的连续段数*2+O的个数的总期望。 ∑ai我们可以理解为O的总个数,所以它的期望为∑pi; C(ai, 2)*2我们可以认
为是连续ai个O中任意选两个点,两个点形成的段必然长度大于1,所以 ∑ C(ai, 2)*2可以理解为长度大于1的连续段数*2。我们设dp[i]
为以i结尾的连续O的段数。那么由期望公式,dp[i]=p[i]×(dp[i - 1]+1)+(1-p[i])*0=p[i]×(dp[i - 1]+1),且dp[i]-p[i]×1才表示以i结尾的长度大
于1的连续O的段数,所以ans+=2×(dp[i] - p[i]×1)。详见代码:
/********************************************************* file name: codeforces235B.cpp author : kereo create time: 2015年02月02日 星期一 13时02分36秒 *********************************************************/ #include<iostream> #include<cstdio> #include<cstring> #include<queue> #include<set> #include<map> #include<vector> #include<stack> #include<cmath> #include<string> #include<algorithm> using namespace std; typedef long long ll; const int sigma_size=26; const int N=100+50; const int MAXN=100000+50; const int inf=0x3fffffff; const double eps=1e-8; const int mod=100000000+7; #define L(x) (x<<1) #define R(x) (x<<1|1) #define PII pair<int, int> #define mk(x,y) make_pair((x),(y)) int n; double dp[MAXN],p[MAXN]; int main(){ while(~scanf("%d",&n)){ double ans=0; for(int i=1;i<=n;i++){ scanf("%lf",&p[i]); ans+=p[i]; } dp[0]=0; for(int i=1;i<=n;i++){ dp[i]=p[i]*(1+dp[i-1]); ans+=2*(dp[i]-1*p[i]); } printf("%.15f\n",ans); } return 0; }
codeforces 235B Let's Play Osu! 概率dp
时间: 2024-10-18 17:32:15