bzoj4318/洛谷P1654OSU!(期望dp,立方版本)

src:https://www.luogu.org/problemnew/show/P1654

解答:https://oi.men.ci/bzoj-4318/

方法同平方版本

思路:求期望,如求E(f[i]),我们要确定 f[ i ] 有几种可能,这里的可能就是pi和1-pi两种,然后各种情况的期望乘上各种情况的可能性大小

x表示i-1位置的连续长度,f[i-1] = E(x^3)  f[i]-f[i-1]=E((x+1)^3)-E(x^3)=E(3*x^2+3*x+1)=3*E(x^2)+3*Ex+1

所以求f[i] , E(f[ i ]) = f[ i-1 ]*(1-p[i]) + (f[ i-1 ]+3*E(g[i-1]^2) + 3*E(g[i-1]) + 1)*p[i]     

这里一定要搞明白的一点是f[i-1]是(Ex)^3还是E(x^3)!!!因为我们的计算目标是x^3,所以f[i-1]的期望是E(x^3)

讲解 E(x^3)为什么与(Ex)^3不同,假设x取到1 2 4的可能性分别为0. 3 0.3 0.4,那么Ex=1 * 0.3 + 2 * 0.3 + 4 * 0.4,而E(x^3)=1^3 * 0.3 + 2^3 * 0.3 + 4^3 * 0.4,很明显不是三次方关系嘛~~~

ac代码:

#include<bits/stdc++.h>
using namespace std;
#define per(i,a,b) for(int i=a;i <= b;i++)
#define max(a,b) a=max(a,b)
#define min(a,b) a=min(a,b)
#define sz(x) (int)x.size()
typedef long long ll;
ll gcd(ll a,ll b){while(b){ll t=b;b=a%b;a=t;}return a;}
const int inf=0x3f3f3f3f;
const int mod=1000000007;
#define siz 100001
double f[siz],p[siz];//g[siz]改成ex1和ex2,分别表示g[i]的一次和二次
double ex1[siz],ex2[siz];
int n;  //f(i)表示以第i个字符结尾的期望得分,g(i)表示以第i个字符结尾连续的o的期望长度。 

int main()
{
    scanf("%d",&n);
    for(int i = 1;i <= n;i++){
        scanf("%lf",&p[i]);
        ex1[i]=(ex1[i-1]+1)*p[i];
        ex2[i]=(ex2[i-1]+2*ex1[i-1]+1)*p[i];
        f[i]=f[i-1]+(3*ex2[i-1]+3*ex1[i-1]+1)*p[i];
    }
    printf("%.1f\n",f[n]);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/WindFreedom/p/9495881.html

相关文章