洛谷 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;
}
原文地址:https://www.cnblogs.com/lipeiyi520/p/13623919.html