• P1654 OSU! 期望概率DP


    P1654 OSU!

    题目链接

    ​ 期望概率DP。

    ​ 设(x)为连续1的个数,那么多一个1他增加的贡献就是:((x + 1) ^ 3 - x ^ 3 = 3 * x ^ 2 + 3 * x + 1)

    ​ 所以我们需要维护(x)的期望和(x ^ 2)的期望。

    (x)的期望:(x[i] = (x[i - 1] + 1) * p[i])

    (x ^ 2)的期望:(x2[i] = (x2[i - 1] + 2 * x[i - 1] + 1) * p[i])

    ​ 答案的期望:(x3[i] = x3[i - 1] + (3 * x2[i - 1] + 3 * x[i - 1] + 1) * p[i])
    有一个地方困扰了我好久,就是为什么算x, x2的时候要把x[i - 1], x2[i - 1]括到括号里,而x3就不用。
    首先要清楚x,x2数组的定义是结尾为i的连续的1的长度,结尾为i的连续的1的长度的平方。而x3数组的定义是最终答案的期望,并不是结尾为i的连续的1的长度的三次方。
    所以对于x3:(ans = displaystyle sum_{i=1}^{n} E[i]),对于x,x2就是i-1的期望加上新的贡献再乘上概率。
    或者也可以这么写:(x3[i] = (x3[i - 1] + 3 * x2[i - 1] + 3 * x[i - 1] + 1) * p[i] + x3[i - 1] * (1 - p[i]))

    #include <bits/stdc++.h>
        
    using namespace std;
        
    inline long long read() {
        long long s = 0, f = 1; char ch;
        while(!isdigit(ch = getchar())) (ch == '-') && (f = -f);
        for(s = ch ^ 48;isdigit(ch = getchar()); s = (s << 1) + (s << 3) + (ch ^ 48));
        return s * f;
    }
        
    
    const int N = 1e5 + 5;
    int n;
    double a[N], x[N], x_2[N], x_3[N];
    
    int main() {
        
        n = read();
        for(int i = 1;i <= n; i++) scanf("%lf", &a[i]);
        for(int i = 1;i <= n; i++) {    
            x[i] = (x[i - 1] + 1) * a[i];
            x_2[i] = (x_2[i - 1] + 2 * x[i - 1] + 1) * a[i];
            x_3[i] = x_3[i - 1] + (3 * x_2[i - 1] + 3 * x[i - 1] + 1) * a[i];
        }
        printf("%.15lf", x_3[n]);
    
        return 0;
    }
    
  • 相关阅读:
    转 sql 时间转换格式 convert(varchar(10),字段名,转换格式)
    C#页面添加提交数据后跳出小弹窗的功能
    解决粘包问题
    粘包问题
    模拟ssh远程执行命令
    基于TCP协议的socket套接字编程
    Linux和git使用
    osi七层协议
    TCP协议的三次握手和四次挥手
    C/S 和 B/S架构
  • 原文地址:https://www.cnblogs.com/czhui666/p/13776199.html
Copyright © 2020-2023  润新知