Tyvj1952 Easy OSU
EASY
对于每一位分别计算对答案的贡献,因为期望具有可加性,所以E[i]相加就是最后答案
l记录到当前位最大连续1的长度
s[i]=='o',第i位对答案的贡献= (l+1)^2-l^2=2*l+1;l=l+1;
s[i]=='x' 第i位对答案的贡献=0 ,l=0
s[i]=='?' 0.5的概率为1,贡献2*l+1;
0.5的概率为0,贡献0
l=0.5*(l+1)+0.5*0
#include<iostream> #include<cstdio> #include<cstring> #define N 100005 using namespace std; int n; double t,l[N],l2[N]; int main() { double ans=0.0; scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%lf",&t); ans+=t*((double)3.0*l2[i-1]+(double)3.0*l[i-1]+(double)1.0); l[i]=(l[i-1]+1)*t; l2[i]=(l2[i-1]+2.0*l[i-1]+1)*t; } printf("%0.1lf",ans); // while(1); return 0; }
OSU
方法和上面差不多,只是特别注意平方的期望和期望的平方不同,所以开两个数组,f[i]表示前i位长度的期望,g[i]表示前i位长度的平方的期望
对于每一位的贡献=(l+1)^3-l^3=3*l^2+3*l+1=3*g[i]+3*f[i]+1
f[i]很好求,按照上面的方法分类讨论直接求
此时,前i-1位的长度为f[i-1],如果下一位为1,则
g[i]=pi*g[i-1]=pi*E[(f[i-1]+1)^2]=pi*E[f[i-1]^2+2*f[i-1]+1]=E(f[i-1]^2)+2*E(f[i-1])+1(E表示期望)
所以g[i]=g[i+1]+2*f[i-1]+1;
#include<iostream>
#include<cstdio>
#include<cstring>
#define N 100005
using namespace std;
int n;
double t,l[N],l2[N];
int main()
{
double ans=0.0;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%lf",&t);
ans+=t*((double)3.0*l2[i-1]+(double)3.0*l[i-1]+(double)1.0);
l[i]=(l[i-1]+1)*t;
l2[i]=(l2[i-1]+2.0*l[i-1]+1)*t;
}
printf("%0.1lf",ans);
// while(1);
return 0;
}