洛谷 P1654 OSU!

题目传送门

期望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;
}
posted @ 2020-09-06 22:08  Mr^Simon  阅读(79)  评论(0编辑  收藏  举报