bzoj4318 OSU!

 

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

 

正解:期望$dp$。

期望满足线性性,但期望的平方和三次方不满足线性性。

于是我们维护一下结尾全$1$序列长度和它的平方就行了。

$(x+1)^{3}=x^{3}+3x^{2}+3x+1$,$(x+1)^{2}=x^{2}+2x+1$。

直接$dp$的时候一起转移就行,注意如果当前位为$0$那么$x$直接变成$0$。

 

 1 #include <bits/stdc++.h>
 2 #define il inline
 3 #define RG register
 4 #define ll long long
 5 
 6 using namespace std;
 7 
 8 long double p,a,b,c;
 9 int n;
10 
11 il int gi(){
12   RG int x=0,q=1; RG char ch=getchar();
13   while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
14   if (ch=='-') q=-1,ch=getchar();
15   while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar();
16   return q*x;
17 }
18 
19 int main(){
20 #ifndef ONLINE_JUDGE
21   freopen("osu.in","r",stdin);
22   freopen("osu.out","w",stdout);
23 #endif
24   n=gi();
25   for (RG int i=1;i<=n;++i){
26     scanf("%Lf",&p);
27     c=(c+3*b+3*a+1)*p+c*(1-p);
28     b=(b+2*a+1)*p,a=(a+1)*p;
29   }
30   printf("%0.1Lf\n",c); return 0;
31 }

 

posted @ 2017-08-16 07:34  wfj_2048  阅读(208)  评论(0编辑  收藏  举报