3次方的期望dp

     osu 是一款群众喜闻乐见的休闲软件。
    我们可以把osu的规则简化与改编成以下的样子:
    一共有n次操作,每次操作只有成功与失败之分,成功对应1,失败对应0,n次操作对应为1个长度为n的01串。在这个串中连续的 X个1可以贡献X^3 的分数,这x个1不能被其他连续的1所包含(也就是极长的一串1,具体见样例解释)
    现在给出n,以及每个操作的成功率,请你输出期望分数,输出四舍五入后保留1位小数。

Input
    第一行有一个正整数n,表示操作个数。接下去n行每行有一个[0,1]之间的实数,表示每个操作的成功率。

Output
    只有一个实数,表示答案。答案四舍五入后保留1位小数。

Sample Input
    3
    0.5
    0.5
    0.5
Sample Output
    6.0
Hint

    【样例说明】

    000分数为0,001分数为1,010分数为1,100分数为1,101分数为2,110分数为8,011分数为8,111分数为27,总和为48,期望为48/8=6.0

    N<=100000


题意 : 给你一个长度 n ,代表接下来串的长度大小为 n ,得分的规则是区间内连续的串的长度的3次方累加,求最终期望的得分

思路分析 : 考虑若当前串的长度为 L , 那么增加一个单位长度后串的长度期望为 (L+1)* P , P 表示概率, 那么得分的增加为 (L+1)^3 - L^3  = 3*L^2 + 3*L + 1

   注意 : 平分的期望是不等于期望的平分的 , 因此这里我们需要再去计算一下平方的期望 , 每一次平方的期望为 (L+1)^2 - L^2 , 即 2*L + 1即可

代码示例 :

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;

int n;
double p[maxn], l[maxn], l2[maxn];
double dp[maxn];

int main () {

    cin >> n;
    for(int i = 1; i <= n; i++) scanf("%lf", &p[i]);

    for(int i = 1; i <= n; i++){
        l[i] = (l[i-1]+1)*p[i];
        l2[i] = (l2[i-1]+2*l[i-1]+1)*p[i];
        dp[i] = dp[i-1]+(1.0+3*l2[i-1]+3*l[i-1])*p[i];
    }
    printf("%.1lf\n", dp[n]);
    return 0;
}

 

posted @ 2018-08-17 18:37  楼主好菜啊  阅读(776)  评论(0编辑  收藏  举报