bzoj1419(期望與DP)

版權聲明:本文爲博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/M_AXSSI/article/details/52336587

4318: OSU!

Time Limit: 2 Sec  Memory Limit: 128 MB
Submit: 388  Solved: 306
[Submit][Status][Discuss]

Description

osu 是一款羣衆喜聞樂見的休閒軟件。 
我們可以把osu的規則簡化與改編成以下的樣子: 
一共有n次操作,每次操作只有成功與失敗之分,成功對應1,失敗對應0,n次操作對應爲1個長度爲n的01串。在這個串中連續的 X個1可以貢獻X^3 的分數,這x個1不能被其他連續的1所包含(也就是極長的一串1,具體見樣例解釋) 
現在給出n,以及每個操作的成功率,請你輸出期望分數,輸出四捨五入後保留1位小數。 

Input

第一行有一個正整數n,表示操作個數。接下去n行每行有一個[0,1]之間的實數,表示每個操作的成功率。 

Output

只有一個實數,表示答案。答案四捨五入後保留1位小數。 

Sample Input

3
0.5
0.5
0.5

Sample Output

6.0

HINT

【樣例說明】 

000分數爲0,001分數爲1,010分數爲1,100分數爲1,101分數爲2,110分數爲8,011分數爲8,111分數爲27,總和爲48,期望爲48/8=6.0 

N<=100000


解題思路:期望與概率,終於手推出來了。首先明確每個點

的貢獻如何計算,每個點的價值是:假設當前點前面有L個一

再前面一個0,那麼它的價值就是3*L²+3*L+1,那麼我們就得出了

ans的計算公式爲對於每個點x累加(3*L²+3*L+1)*sug(x)/sug(x-L+1)*(1-p[x-L+1])

這個式子可以進行轉化,發現答案就爲1*sug(x)/sug(x-1)+6*sug(x)/sug(x-2)······

那就可以O(n)求了。



#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n;
long double a[100100];


int main()
{
  scanf("%d",&n);
  long double a1=0,a2=0;
  long double sug=0; a[0]=1;
  double x; 
  scanf("%lf",&x); 
  a[1]=x; a2=a[1]; sug=a[1]; a1=a[1];
  for(int i=2;i<=n;++i)
   {
    double x;
    scanf("%lf",&x); a[i]=x;
    sug=sug*a[i];
a1=a1*a[i]+6*sug-a[i-1]*a[i]+a[i];
sug+=a[i];
a2+=a1;
   }
  printf("%.1lf",(double)a2);
}

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