codeforces 235B Let's Play Osu! 概率dp

題意:給定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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章