Codeforces 235B Let's Play Osu! (概率dp求期望+公式变形)

B. Let‘s Play Osu!

time limit per test:2 seconds

memory limit per test:256 megabytes

You‘re playing a game called Osu! Here‘s a simplified version of it. There are
n clicks in a game. For each click there are two outcomes: correct or bad. Let us denote correct as "O", bad as "X", then the whole play can
be encoded as a sequence of n characters "O" and "X".

Using the play sequence you can calculate the score for the play as follows: for every maximal consecutive "O"s block, add the square of its length (the number of characters "O")
to the score. For example, if your play can be encoded as "OOXOOOXXOO", then there‘s three maximal consecutive "O"s block "OO", "OOO",
"OO", so your score will be
22?+?32?+?22?=?17. If there are no correct clicks in a play then the score for the play equals to
0.

You know that the probability to click the
i-th (1?≤?i?≤?n) click correctly is
pi. In other words, the
i-th character in the play sequence has
pi probability to be "O",
1?-?pi to be "X". You task is to calculate the expected score for your play.

Input

The first line contains an integer
n (1?≤?n?≤?105) — the number of clicks. The second line contains
n space-separated real numbers
p1,?p2,?...,?pn
(0?≤?pi?≤?1).

There will be at most six digits after the decimal point in the given
pi.

Output

Print a single real number — the expected score for your play. Your answer will be considered correct if its absolute or relative error does not exceed
10?-?6.

Sample test(s)

Input

3
0.5 0.5 0.5

Output

2.750000000000000

Input

4
0.7 0.2 0.1 0.9

Output

2.489200000000000

Input

5
1 1 1 1 1

Output

25.000000000000000

Note

For the first example. There are 8 possible outcomes. Each has a probability of 0.125.

  • "OOO"
    ?→? 32?=?9;
  • "OOX"
    ?→? 22?=?4;
  • "OXO"
    ?→? 12?+?12?=?2;
  • "OXX"
    ?→? 12?=?1;
  • "XOO"
    ?→? 22?=?4;
  • "XOX"
    ?→? 12?=?1;
  • "XXO"
    ?→? 12?=?1;
  • "XXX"
    ?→? 0.

So the expected score is

题目链接:http://codeforces.com/contest/235/problem/B

题目大意:长度为n的序列,每个位置上出现O的概率为pi,得分为连续k个O的k^2分,现在求得分的期望

题目分析:n^2 = 2 * C(2, n) + n,问题转化对于每段连续的O,求其子段长度大于等于2的段数*2再加上连续O的个数,比如OOO有三个O,两个OO,一个OOO,所以分数为2*3+3 = 9 = 3^3,这样问题就简单了,考虑每个点i,其能构成的长度为i,i-1,i-2,...,2,对应的概率为p1*p2*...*pi,p2*p3*...*pi,...,pi-1*pi

为方便表示,设(j, i)为p[j]*p[j+1]*...*p[i-1]*p[i],令dp[i] = Σ(j,i)其中1 <= j < i

则有dp[0] = 0,dp[2] = p[1]*p[2],dp[3] = p[1]* p[2] *p[3] + p[2]*p[3],可以看出

dp[i] = (dp[i - 1] + p[i - 1]) * p[i],dp[1]+dp[2]+dp[3] = p[1]*p[2] + p[2]*p[3] + p[1]*p[2]*p[3],发现正好是长度为3时,连续个数大于等于2的情况,所以之后我们把每个dp[i]的值乘2累加就是C(2,n)*2对答案的贡献,再加上Σpi,即每个O对答案的贡献就是最终的答案,所以可以写成

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int const MAX = 1e5 + 5;
double dp[MAX], p[MAX];

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

仔细观察dp方程,dp[1] = 0,dp[i] = (dp[i - 1] + p[i - 1]) * p[i],这个递推式可以直接通过变量的循环实现,具体方法是先设一个tmp,在第i次循环时tmp就代表p[i],再设一个now表示多加一位时,新增的连续O长度大于1的情况,然后直接ans += 2 * now + tmp即长度大于1的每个要乘2再加本次添加的那个长度为1的

比如n=3时有p1,p2,p3计算过程为

i=1,tmp=p1,now=0,ans += p1,now = p1

i=2,tmp=p2,now=p1*p2,ans += 2*now + tmp = 2p1p2 + p2 + p1,now = p2 + p1p2

i=3,tmp=p3,now=p2p3 + p1*p2*p3,ans += 2*now + tmp = 2p2p3 + 2p1p2p3 + p3 + 2p1p2 + p2 + p1

所以ans = p1 + p2 + p3 + 2p1p2 + 2p2p3 + 2p1p2p3,这正好是我们定义的答案,所以还可以不开数组

#include <cstdio>

int main()
{
    int n;
    scanf("%d", &n);
    double ans = 0, tmp = 0, now;
    while(n --)
    {
        scanf("%lf", &tmp);
        now *= tmp;
        ans += 2 * now + tmp;
        now += tmp;
    }
    printf("%.10f\n", ans);
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

Codeforces 235B Let's Play Osu! (概率dp求期望+公式变形)

时间: 2024-12-22 06:46:05

Codeforces 235B Let's Play Osu! (概率dp求期望+公式变形)的相关文章

codeforces 235B Let&#39;s Play Osu! 概率dp

题意:给定n表示有n个格子,下面每个格子为O的概率是多少.对于一段连续 x 个O的价值就是 x^2 ;求获得的价值的期望是多少. 思路:n^2=n×(n-1)+n,设ai为第i段连续O的长度,∑ai^2 = ∑[ ai+ ai*(ai-1) ] = ∑ ai*(ai-1) + ∑ai = ∑ C(ai, 2)*2 + ∑ai,那么问题可以转 化为求长度大于1的连续段数*2+O的个数的总期望. ∑ai我们可以理解为O的总个数,所以它的期望为∑pi: C(ai, 2)*2我们可以认 为是连续ai个O

Codeforces 235B Let&#39;s Play Osu! 概率dp(水

题目链接:点击打开链接 给定n表示有n个格子 下面每个格子为O的概率是多少. 对于一段连续 x 个O的价值就是 x*x ; 问: 获得的价值的期望是多少. 思路: 把公式拆一下.. #include <cstdio> const int N = 100005; double dp[N][2], p[N]; int main(){ int n; scanf("%d", &n); for(int i = 1; i <= n; i ++) { scanf("

HDU 4405 Aeroplane chess (概率DP求期望)

题意:有一个n个点的飞行棋,问从0点掷骰子(1~6)走到n点需要步数的期望 其中有m个跳跃a,b表示走到a点可以直接跳到b点. dp[ i ]表示从i点走到n点的期望,在正常情况下i点可以到走到i+1,i+2,i+3,i+4,i+5,i+6 点且每个点的概率都为1/6 所以dp[i]=(dp[i+1]+dp[i+2]+dp[i+3]+dp[i+4]+dp[i+5]+dp[i+6])/6  + 1(步数加一). 而对于有跳跃的点直接为dp[a]=dp[b]; #include<stdio.h>

HDU4336-Card Collector(概率DP求期望)

Card Collector Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2195    Accepted Submission(s): 1034 Special Judge Problem Description In your childhood, do you crazy for collecting the beautifu

HDU3853-LOOPS(概率DP求期望)

LOOPS Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 125536/65536 K (Java/Others) Total Submission(s): 1864    Accepted Submission(s): 732 Problem Description Akemi Homura is a Mahou Shoujo (Puella Magi/Magical Girl). Homura wants to help h

HDU4405-Aeroplane chess(概率DP求期望)

Aeroplane chess Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1182    Accepted Submission(s): 802 Problem Description Hzz loves aeroplane chess very much. The chess map contains N+1 grids lab

HDU 4050 wolf5x (概率DP 求期望)

题意:有N个格子,1~N,起点在0,每个格子有一个状态(0,1,2,3),每次可以跨[a,b]步, 问走完N个格子需要步数的期望,每次尽量走小的步数,即尽量走a步,不能则走a+1,-- 状态0意味着你不能踏进对应的网格. 状态1意味着你可以??步入网格用你的左腿. 状态2意味着你可以??步入网格用你的右腿. 状态3意味着你可以进入网格用任何你的腿,而接下来的步骤中,您可以使用任何的腿;即你不需要遵循上述规则. 思路:借鉴了各路大神的思想理解了下. dp[i][j] :表示走到第 i 个格子在 j

POJ 2096 Collecting Bugs(概率DP求期望)

传送门 Collecting Bugs Time Limit: 10000MS Memory Limit: 64000K Total Submissions: 4333 Accepted: 2151 Case Time Limit: 2000MS Special Judge Description Ivan is fond of collecting. Unlike other people who collect post stamps, coins or other material stu

POJ 2096:Collecting Bugs 概率DP求期望

Collecting Bugs 题目连接: http://poj.org/problem?id=2096 题意: Ivan喜欢收集bug,他每天都会找到一个bug,找到的这个bug有一种属性并且属于一个子系统,bug共有n种属性,子系统共有s个 (0<n, s≤1000),求Ivan集齐了n种bug且每个子系统都有bug的期望. 题解: 第一道求期望的题,令dp[i][j]表示系统已经有了i个系统的全部j种bug并且要得到所有bug的天数的期望,因此dp[n][s]=0,而dp[0][0]则是所