题目传送门
期望dp,f[i]表示到第i位,1~n的期望收益.
对于每一位,如果操作成1,那收益就会变成:
((x+1)^3 = (x+1)^2(x+1) = (x^2+2x+1)(x+1) = x^3+3x^2+3x+1)
显然我们在这一位获得的收益为(3x^2+3x+1),不难发现,这是一个二次多项式,所以我们要用两个数组分别递推一次和二次.
(a[i] = (a[i-1] + 1) * p[i])一次
(b[i] = (b[i-1] + 2 * a[i-1] + 1) * p[i])二次
(f[i] = (f[i-1] + 3 * b[i-1] + 3 * a[i-1] + 1) * p[i])
而我们f[i]表示的是1~n的收益,所以就要直接用上一位的f加上这一位新的收益即可,具体看代码.
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n;
double f[100001],p[100001],a[100001],b[100001],ans;
int main() {
scanf("%d",&n);
for(int i = 1;i <= n; i++)
scanf("%lf",&p[i]);
for(int i = 1;i <= n; i++) {
a[i] = (a[i-1] + 1) * p[i];
b[i] = (b[i-1] + a[i-1] * 2 + 1) * p[i];
f[i] = f[i-1] + (3 * b[i-1] + 3 * a[i-1] + 1) * p[i];
}
printf("%.1lf",f[n]);
return 0;
}