codeforces 235 B lets play osu!

cf235B

一道有意思的题。(据说是美少女(伪)计算机科学家出的,hh)

根据题目要求,就是求ni^2的和。

而n^2=n*(n-1)+n; n*(n-1)=C(n,2)*2;

所以∑ai^2=∑ai+2*∑C(n,2)

化为求连续长度大于2的序列个数;这样好像还是不太好直接做

设dp【i】=以i结尾的期望长度; dp【0】=dp【1】=0,dp【2】=p1p2,dp【3】=p1p2p3+p2p3=(dp【2】+p【2】)*p3  ...

得dp【i】=p【i】*(dp【i-1】+p【i-1】)

而发现dp【0】+dp【1】+...+dp【i】恰好包括了长度为i时序列长度超过2的所有情况,就可以接着做了

 

另一种思路:

设当前长为L,则下一个若也为o,那么贡献增加为(L+1)^2-L^2=2L+1 

设dp【i】=以i结尾的期望长度;

得到dp【i】=(dp【i-1】+1)*p【i】 

就可以累加了

 

代码

#include<bits/stdc++.h>
using namespace std;

const int maxn=100010;
int n;

double ans;
int main()
{
    while(scanf("%d",&n)==1)
    {
        ans=0;double cnt=0;double p;
        for(int i=1;i<=n;i++)
        {
            scanf("%lf",&p);

            ans+=(2*cnt+1)*p;
            cnt=(cnt+1)*p;
        }


        printf("%.15lf\n",ans);
    }
    return 0;
}

 

 

posted @ 2018-09-25 23:58  Erio  阅读(193)  评论(0编辑  收藏  举报