zoukankan      html  css  js  c++  java
  • 【期望dp】——洛谷P1654 OSU!

    题目传送门:

    第一眼,看不懂题意。

    实际上是一道很有意思的期望dp题目。

    解答参考了一下这位大大的一篇讲解:go


    设a[i]表示第i个位置为1的前i位的期望长度。

    容易知道:

    a[i] = (a[i-1]+1) * p[i].

    我们要求的是三次项,而根据期望的性质,可以用立方和公式展开,得到二次项和一次项。

    设二次的a[i]表示为b[i],有b[i] = a[i]^2

    b[i] = (a[i-1]+1)^2 = (a[i-1]^2) + 2*a[i-1] + 1

         = b[i-1]^2 + 2*a[i-1] + 1.

      那么也可以得到三次项,但是光求三次项没有意义,因为我们要求的是n的期望,所以只求出某位为1的情况还不够,还要算上某位为0的情况,这一情况又要由前面一位为0和为1共同得到,到了最后我们还是要求出每一位都为0的情况。

      所以改变一下思路,从一开始就求答案:

    对三次项f[i]:

    f[i] = (f[i-1] + 3*a[i-1] + 3*b[i-1] + 1) * p[i](第i位为1)

       + f[i-1] * (1 - p[i])           (第i位不为1)

       = f[i-1] + (3*a[i-1] + 3*b[i-1] + 1) * p[i]

    最后输出答案即可!

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int N=1e5+10;
     4 int n;
     5 double p[N];
     6 double a[N],b[N],dp[N];
     7 int main(){
     8     scanf("%d",&n);
     9     for(int i=1;i<=n;i++){
    10         scanf("%lf",&p[i]);
    11     }
    12     for(int i=1;i<=n;i++){
    13         a[i]=(a[i-1]+1)*p[i];
    14         b[i]=(b[i-1]+2*a[i-1]+1)*p[i];
    15         dp[i]=dp[i-1]+(3*a[i-1]+3*b[i-1]+1)*p[i];
    16     }
    17     printf("%.1lf",dp[n]);
    18     return 0;
    19 }

    所以说数学思想很重要啦! 

    ——抓住了时间,却不会利用的人,终究也逃不过失败的命运。
  • 相关阅读:
    软件设计中的立足点
    Clojure基础
    团队凝聚力
    执行力与领导力
    工作与生活
    分离焦虑OR责任焦虑
    保持激情
    立足点
    论研发管理--开篇
    初级码农常犯错误
  • 原文地址:https://www.cnblogs.com/Nelson992770019/p/11537374.html
Copyright © 2011-2022 走看看