事件与概率

找东西的诱惑

问题描述:

现在书桌上有8个抽屉,分别用数字1~8表示,每次拿到一个文件后,都会把这份文件随机地放到一个抽屉里,但是,我非常粗心,有1/5的概率会忘了把文件放进抽屉里,最终把这个文件丢失,现在,我要找一份非常重要的文件,我会按照顺序打开每一个抽屉,知道找到这份文件为止,或者发现给弄丢了,计算问题的答案?

1.假如我打开了第一个抽屉,发现里面什么也没有,那么,这份文件在其他7个抽屉里的概率是多少?

答案是7/9,有1/5的概率弄丢,就是平均10份文件就有2份文件弄丢,其余8份平均到了8个抽屉里,假设那2份丢掉的文件我找了回来,也分别占用了1个抽屉,就是把问题增加了两个虚拟的抽屉,只不过不允许打开最后的2个抽屉,现在分别求:找过了n个抽屉但没有发现文件,这份文件在其余10-n个抽屉中,但是我只能打开其中前8-n个抽屉。答案显然是(8-n)/(10-n)。

红色笔

问题描述:

在40支圆珠笔中有30支黑色的,另外10支是红色的。从中任意取出4支,计算至少有1支红色笔的概率。

设从40支笔中任取4支,恰有1支,2支,3支,4支红笔的事件分别记为A,B,C,D。则:

P(A)=C(1,10)*C(3,30)/C(4,40)

P(B)=C(2,10)*C(2,30)/C(4,40)

P(C)=C(3,10)*C(1,30)/C(4,40)

P(D)=C(4,10)*C(0,30)/C(4,40)

跟据题意:事件A,B,C,D两两互斥,所以P(A)+P(B)+P(C)+P(D)=0.7

当然这个题从对立事件的概率来分析,设从40支笔中取4支笔全是黑色的事件为A,则P(A)=0.3,所以,对立事件的概率为0.7

银行密码

问题描述:

某银行储蓄卡的密码是6位数字号码,每位上数字均可取0到9这10个 数字。忘记了银行密码。请计算:

如果他记住密码中只含有一个1,两个2,三个3,那么他按一次密码,正好按对的概率是多少?

因为只会去按一次1,2次2和3次3,所以共有C(1,6)*C(2,5)*C(3,3)=60种按法,所以答案是1/60

 

概率(抛骰子)

题目描述

    众所周知,骰子是一个六面分别刻有一到六点的立方体,每次投掷骰子,从理论上讲得到一点到六点的概率都是1/6。今有骰子一颗,连续投掷N次,问点数总和大于等于X的概率是多少?

输入

仅有一行包含二个用空格隔开的整数,分别表示n和x,其中1<=N<=24,0<=x<150。

输出

仅有一行包含一个有理数,要求以最简的形式精确地表达出连续投掷N次骰子,总点数大于等于X的概率。

样例输入

3 9

样例输出

20/27

解题思路:

       一拿到题目,第一个反应是枚举,但是怎么枚举呢,怎么记录状态呢?n到24!按一下计算器,6^24都已经超到哪里去了,几亿亿了!不过,当然有解决办法,那就是用——伟大的DP!现将f[0,0]赋成1,用二维背包第一维记录抛掷的次数,第二维记录当前的数字,然后,三重循环,外循环i从0枚举到n-1,表示当前用了几个骰子,中循环j从0枚举到i*6,表示当前累加到多少了,内循环k从1枚举到6,动态方程为f[i+1][j+k]+=f[i][j],总方案数是6^n,将大于等于x的方案数累加起来,但是要注意大于等于x的方案数如果等于0,就要输出0。然后,利用递归(辗转相除法)算出最大公约数,分别去除以最大公约数,当除数为1时,就输出1,否则正常输出。(ps:要将大于等于x的方案数的累加器,总方案累加器,二维背包,以及递归的输入量,返回量都设成 unsigned long long,否则在极端数据时是会炸的)

附上代码:


#include<iostream>
#include<cstdio>

using namespace std;

typedef unsigned long long ll;

ll dp[25][200],ans=0,tmp=1;

ll gcd(ll x,ll y)
{
    return x==0?y:gcd(y%x,x);
}

int main()
{
    int n,x;
    scanf("%d%d",&n,&x);
    dp[0][0]=1;
    for(int i=0;i<n;i++){
        tmp*=6;
        for(int j=0;j<=i*6;j++){
            for(int k=1;k<=6;k++){
                dp[i+1][j+k]+=dp[i][j];
            }
        }
    }
    for(int i=x;i<=6*n;i++){
        ans+=dp[n][i];
    }
    if(ans==0){
        printf("%d\n",0);
    }
    ll z=gcd(ans,tmp);
    ans/=z;
    tmp/=z;
    if(tmp==1){
        printf("%d\n",1);
    }else{
        printf("%lld/%lld\n",ans,tmp);
    }
    return 0;
}

三角形的概率

问题描述:

随机产生3个一定范围内的正整数,作为一个三角形的三条边,求它们能构成一个三角形的概率是多少?

问题分析:

设产生的3个数分别为a,b,c,假设a<=b<=c,则只要a+b>c,就能构成一个三角形,也即要求a/c+b/c>1,换言之就是两个纯小数(x=a/c,y=b/c)的和加起来大于1,建立一个直角坐标系,x,y分别对应x轴,y轴,而x,y的取值范围都是0到1(不包括0,包括1),在这样一个正方形区域内,直线x+y=1把它分成相等的两半,其中一半的区域内x+y>1,而另一半x+y<1.所以概率就是1/2.

Football

传送门

题解:概率dp,其实题意理解都不难,想法也不难,最重要的就是怎么进行dp,巧妙地竞赛图关系,设dp[i][j]表示第i场比赛第j人赢的概率,则dp[i][j]=dp[i-1][j]*dp[i-1][k]*p[j][k],这个k是第i场所要面对的对手,这个对手怎么算呢?非常有技巧,由于竞赛图的关系,所以判断((j>>(i-1))^1)与(k>>(i-1))是不是相等,这个把进制写出来,然后与比赛回合推断下,就看出其中的巧妙了。

附上代码:


#include<iostream>
#include<cstdio>
#include<cstring>

using namespace std;

int n;
double p[200][200];
double dp[8][200];

int main()
{
    while(~scanf("%d",&n)&&n!=-1){
        for(int i=0;i<(1<<n);i++){
            for(int j=0;j<(1<<n);j++){
                scanf("%lf",&p[i][j]);
            }
        }
        memset(dp,0,sizeof(dp));
        for(int i=0;i<(1<<n);i++){
            dp[0][i]=1;
        }
        for(int i=1;i<=n;i++){
            for(int j=0;j<(1<<n);j++){
                for(int k=0;k<(1<<n);k++){
                    if(((j>>(i-1))^1)==(k>>(i-1))){
                        dp[i][j]+=dp[i-1][j]*dp[i-1][k]*p[j][k];
                    }
                }
            }
        }
        double ans=-1;
        int Ans=-1;
        for(int i=0;i<(1<<n);i++){
            if(dp[n][i]>ans){
                ans=dp[n][i];
                Ans=i;
            }
        }
        printf("%d\n",Ans+1);
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值