OSU!
4318: OSU!
Time Limit: 2 Sec Memory Limit: 128 MB
Submit: 748 Solved: 579
[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
solution:
f[i]表示前i个的总期望 f[i][1]=(f[i-1][0]+1)*p[i]+(f[i-1][1]+(OOXX一坨屎))*p[i];..................① f[i][0]=f[i-1][1]*(1-p[i])+f[i-1][0]*(1-p[i]);//来自TS_huge神犇的点拨......② ①+② f[i]=p[i]+f[i-1]+p[i]*(OOXX一坨屎) f[i]=f[i-1]+p[i]*(1+(OOXX一坨屎)) 我们设x[i]为前i个从后往前最长的1的不间断链,(0<=x[i]<=i) 每次往后加 0 对期望值没有贡献(期望=权值/方案数 加0之后权值没有变化 重点是方案数也没有变化 因为第i位已经确定是0) (ps:我就是因为这个想不通卡了一个下午 虽然代码日了狗的短......) 每次往后加 1 会让x[i-1]+1,再乘以p[i],就是一个我想不懂的概率/期望??? 总之我们先认为它是一个对的期望 然后我们来考虑(OOXX一坨屎)是个什么东西..... 应该是加上 1 对总期望的贡献 让后就是各种神犇blog上写的 加上 1 对总期望的贡献=x[i]^3-x[i-1]^3=(x[i-1]+1(p[i]乘在了外面))^3-x[i-1]^3=3*x[i-1]^2+3*x[i-1]+1; 然后递推的时候就维护 x[i]^2 x[i] 推即可 (2017.7.15 ps:反正我真的不懂这道题)
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #define mem(a,b) memset(a,b,sizeof(a)) 5 #define dd double 6 #define ll long long 7 using namespace std; 8 const int N=100100; 9 10 int n; 11 dd p[N],l[N],l2[N],f[N]; 12 13 int main(){ 14 scanf("%d",&n); 15 for(int i=1;i<=n;++i) 16 scanf("%lf",&p[i]); 17 18 for(int i=1;i<=n;++i) 19 { 20 l[i]=(l[i-1]+1.0)*p[i]; 21 l2[i]=(l2[i-1]+2*l[i-1]+1.0)*p[i]; 22 f[i]=f[i-1]+p[i]*(3.0*l2[i-1]+3.0*l[i-1]+1.0); 23 } 24 printf("%.1lf",f[n]); 25 //while(1); 26 return 0; 27 }