洛谷概率类型心得


前言

原本只是想去水水的,结果发现有 3 3 3道关于 o s u osu osu的题目,于是开始走上了概率的不归路 . . . ... ...
总结下做概率题的方法,顺带洛谷 P 1654 P1654 P1654 P 1365 P1365 P1365 C F 235 B CF235B CF235B的题解


方法&心得

1. 1. 1.警惕所有样例:因为遇上概率的题目一般都会有些奇奇怪怪的样例,如贿赂,听队里的 d a l a o dalao dalao说自己是直接跳过样例然后码 A A A
2. 2. 2.多看些题目,感性理解:概率这种玄学的东西,真的用语言是很难描述的。很多题解都说的很有理,但到了出公式的时候,就有点妙了。所以我们应多练下概率的题目,找到数感
3. 3. 3.由简到繁:在洛谷的三道题尤其可见,题目给出了 x 2 x^2 x2 x 3 x^3 x3,我们往往不是直接算,而是通过拆分,得出与更小指数的 x x x的关系,然后再一层层得出最终答案
4. 4. 4.好像一般不需要用到数组耶(雾:因为我们的概率只跟上一次的结果相关,所以我们没必要保存前面的结果,只需用一个变量记录就好了


题解


P1654 OSU!

分析:

题目要求的是 x 3 x^3 x3,显然直接做会很麻烦,所以我们考虑间接得到答案
假设我们当前这一位是 x x x,在不考虑概率的情况下,我们的下一位就变成了 x + 1 x+1 x+1,而每次增加的都是 x 3 x^3 x3,也就是 ( x + 1 ) 3 (x+1)^3 (x+1)3,我们暴力分解下这个式子,就得到了
x 3 + 3 ∗ x 2 + 3 ∗ x + 1 x^3+3*x^2+3*x+1 x3+3x2+3x+1
现在我们已经找出原式与其更小指数的关系了,然后整道题目就变得清晰了
我们可以通过记录 x x x x 2 x^2 x2,从而得到最终要增加的 x 3 x^3 x3
p p p代表第 i i i位的概率, x 1 x_1 x1 x x x的期望, x 2 x_2 x2 x 2 x^2 x2的期望, a n s ans ans为最终的和
x 1 i = p ∗ ( x 1 i − 1 + 1 ) x1_i=p*(x1_{i-1}+1) x1i=p(x1i1+1)
感觉这个十分显然(逃
其实就是在上一位的期望上多了一位,所以有 + 1 +1 +1,而我们要考虑第 i i i位的概率,所以需要 p ∗ p* p
x 2 i = p ∗ ( x 2 i − 1 + 2 ∗ x 1 i − 1 + 1 ) x2_i=p*(x2_{i-1}+2*x1_{i-1}+1) x2i=p(x2i1+2x1i1+1)
这个式子跟我们推 x 3 x^3 x3一样,其他的跟求 x 1 x1 x1相同
a n s i = a n s i − 1 + p ∗ ( 3 ∗ x 2 i − 1 + 3 ∗ x 1 i − 1 + 1 ) ans_i=ans_{i-1}+p*(3*x2_{i-1}+3*x1_{i-1}+1) ansi=ansi1+p(3x2i1+3x1i1+1)
这个式子就是我们开头所推出的式子,所以就不多说
但对于 a n s i − 1 ans_{i-1} ansi1为什么不用 ∗ p *p p,我想了很久(可能是我太菜了),我是这么认为的,因为 a n s ans ans是一个累加的数组,我们对于以前求到的答案已经在 p ∗ ( 3 ∗ x 2 i − 1 + 3 ∗ x 1 i − 1 + 1 ) p*(3*x2_{i-1}+3*x1_{i-1}+1) p(3x2i1+3x1i1+1)时乘了,如果之后运算再乘的话…错误性显然

代码:

// luogu-judger-enable-o2
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<set>
#include<queue>
#include<vector>
#include<map>
#include<list>
#include<ctime>
#include<iomanip>
#include<string>
#include<bitset>
#include<deque>
#include<set>
#define LL long long
#define mo (LL)1e11
using namespace std;
inline LL read(){
    LL d=0,f=1;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
    while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();}
    return d*f;
}
double x,x1,x2,ans;
int main()
{
    int n=read();
    for(int i=1;i<=n;i++)
    {
    	scanf("%lf",&x);
        ans+=x*(3*x1+3*x2+1);
        x2=x*(x2+2*x1+1);
        x1=x1*x+x*1;
    }
    printf("%.1lf",ans);
    return 0;
}

吹水

之所以现在这道紫题,是因为我觉得之后的两道题都可以以此题为铺垫搞好的理解


P1365 WJMZBMR打osu! / Easy

分析:

这道题本身与上面一题没有太大区别,可我们需要注意, t a ta ta并不是都是不确定的, t a ta ta含有一些确定的东西,所以我们需要开多一个变量,来记录连续的期望

代码:

// luogu-judger-enable-o2
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<set>
#include<queue>
#include<vector>
#include<map>
#include<list>
#include<ctime>
#include<iomanip>
#include<string>
#include<bitset>
#include<deque>
#include<set>
#define LL long long
#define mo (LL)1e11
using namespace std;
inline LL read(){
    LL d=0,f=1;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
    while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();}
    return d*f;
}
char a;
double f,g;
int main()
{
    int n=read();
    for(int i=1;i<=n;i++)
    {
        scanf("%c",&a);
        if(a=='o') f+=2*g+1,g++;
        else if(a=='x') g=0;
        else f+=g+0.5,g=g/2+0.5;
    }
    printf("%.4lf",f);
    return 0;
}

CF235B Let’s Play Osu!

分析

某谷良心双倍经验,跟第一题一模一样,还把 x 3 x^3 x3给扔了 . . .. ..

代码:

// luogu-judger-enable-o2
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<set>
#include<queue>
#include<vector>
#include<map>
#include<list>
#include<ctime>
#include<iomanip>
#include<string>
#include<bitset>
#include<deque>
#include<set>
#define LL long long
#define mo (LL)1e11
using namespace std;
inline LL read(){
    LL d=0,f=1;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
    while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();}
    return d*f;
}
double x,x1,x2,ans;
int main()
{
    int n=read();
    for(int i=1;i<=n;i++)
    {
    	scanf("%lf",&x);
        ans+=x*(2*x1+1);
        x1=x1*x+x*1;
    }
    printf("%.15lf",ans);
    return 0;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值