分析:
首先研究dp方程 dp[i]=(len^3-(len-1)^3)*p;其中有一个三次方差,计算这个三次方差需要维护两个值,即二次方和一次方的转移值,而二次方差需要一次方转移。
一次方转移方法:对于一个位置共有两种情况。一种为1,概率为p,得分为x1[i-1]+1,贡献为p*(x1[i-1]+1);另一种为0,概率为1-p,贡献为0。二次方也相似,于是得到总dp方程:dp[i]=x3[i]-p*x3[i-1](因为x3[i]已考虑当前p的概率,而x3[i-1]需要另乘概率;代码中dp相当于计算一个前缀和)。
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=100005;
int n;
double x1[maxn],x2[maxn],x3[maxn],dp[maxn];
int main()
{
scanf("%d",&n);
double tmp;
for(int i=1;i<=n;i++)
{
scanf("%lf",&tmp);
x1[i]=tmp*(x1[i-1]+1);
x2[i]=tmp*(x2[i-1]+2*x1[i-1]+1);
x3[i]=tmp*(x3[i-1]+3*x2[i-1]+3*x1[i-1]+1);
dp[i]=dp[i-1]+x3[i]-tmp*x3[i-1];
}
printf("%.1lf",dp[n]);
return 0;
}