其他分享
首页 > 其他分享> > [题解] P1654 OSU!

[题解] P1654 OSU!

作者:互联网

[题解] P1654 OSU!

传送门

解题报告

题意描述自己看吧。

考虑到两个公式:

\((a+b)^2=a^2+2ab+b^2\)

\((a+b)^3=a^3+3a^2b+3ab^2+b^3\)

不妨设 DP 数组 \(f[i][0/1]\) 表示第 \(1\) 到 \(i\) 位 \(1\) 的期望个数,其中 \(0\) 维维护原始期望值,\(1\) 维维护 平方的期望值(顺序不可颠倒)。

小细节:\(E(x^2)\not=E^2(x)\)

注意到这个,就可以递推了,因为当前第 \(i\) 位选 \(0\) 对期望没有贡献,所以不用考虑。

因为每次代价都增加 \(1\),也就是平方和立方的增量是 \(1\),利用开始的两个公式和维护的值就可以递推。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <bits/stdc++.h>
#include <algorithm>
using namespace std;
template <typename T>
inline T read(){
	T x=0;char ch=getchar();bool fl=false;
	while(!isdigit(ch)){if(ch=='-')fl=true;ch=getchar();}
	while(isdigit(ch)){
		x=(x<<3)+(x<<1)+(ch^48);ch=getchar();
	}
	return fl?-x:x;
}
const int maxn = 1e5 + 17;
double f[maxn][2],p[maxn],ans[maxn];
int n;
int main(){
	scanf("%d",&n);
	f[0][0]=f[0][1]=0.0;
	for(int i=1;i<=n;i++)scanf("%lf",p+i);
	for(int i=1;i<=n;i++){
		f[i][0]=(f[i-1][0]+1)*p[i];//原始值
		f[i][1]=(f[i-1][1]+2*f[i-1][0]+1)*p[i];//平方的期望值
		ans[i]=ans[i-1]+(3*f[i-1][1]+3*f[i-1][0]+1)*p[i];//立方增量为1
	}
    //具体的说是因为,(x+1)^3=x^3+3*x^2+3*x+1
	printf("%.1lf\n",ans[n]);
	return 0;
}

标签:ch,题解,OSU,P1654,include,getchar
来源: https://www.cnblogs.com/Liang-sheng/p/15134145.html