概率&数学期望训练题集

讲解视频

1.Headshot UVA - 1636:

分析:

分类讨论,比较两种情况下没有子弹射出的概率大小;
(1).如果直接射击,要使得没有子弹射出,且在第一次没有子弹射出的条件下,即求 \(00\) 串数量占 \(00\)\(01\) 总数量的比例(条件概率);
(2).如果要转一下再射击并保证没有子弹,即求串中 \(0\) 的数量占整个串长度的比例;

代码:

#include <bits/stdc++.h>
using namespace std;
char ss[110];
int main()
{
    while(scanf("%s",ss+1)!=EOF)
    {
        int n=strlen(ss+1);
        int a=0,b=0,c=0;
        for(int i=1;i<=n;i++)
            c+=(ss[i]=='0'?1:0);
        for(int i=2;i<=n;i++)
        {
            if(ss[i]=='0'&&ss[i-1]=='0')
                b++;
            else if(ss[i]=='1'&&ss[i-1]=='0')
                a++;
        }
        if(ss[n]=='0'&&ss[1]=='0')
            b++;
        else if(ss[n]=='0'&&ss[1]=='1')
            a++;
        int x=c*(a+b),y=n*b;
        if(y>x)
            printf("SHOOT\n");
        else if(y<x)
            printf("ROTATE\n");
        else
            printf("EQUAL\n");
    }
    return 0;
}

2.Cows and Cars UVA - 10491:

#include <bits/stdc++.h>
using namespace std;
int main()
{
    int a,b,c;
    while(scanf("%d%d%d",&a,&b,&c)!=EOF)
    {
        double ans=(1.0*b*(b-1)+1.0*a*b)/(1.0*(a+b)*(a+b-c-1));
        printf("%.5f\n",ans);
    }
    return 0;
}

3.Probability|Given UVA - 11181:

分析:

由题意可知,该题为一道条件概率。
条件概率公式:

\[P(A_i|B)=\frac{P(A_i*B)}{P(B)} \]

其中,\(P(B)\)\(n\) 个人中恰好有 \(r\) 个人购买商品的概率,\(P(A_i*B)\) 表示 \(n\) 个人中恰好有 \(r\) 个人购买商品且第 \(i\) 个人一定购买的概率。
采用子集枚举的方法,枚举情况求出各个概率。
输入以 \(n=0\) 结束。
代码:

#include <bits/stdc++.h>
using namespace std;
double p[25],ans[25],sum;
void solve(int n,int r)
{
    sum=0;
    for(int i=0;i<n;i++)
        ans[i]=0;
    for(int i=0;i<(1<<n);i++)
    {
        int t=i,cnt=0;
        while(t)
        {
            if(t&1)
                cnt++;
            t>>=1;
        }
        if(cnt!=r)
            continue;
        double tmp=1.0;
        for(int j=0;j<n;j++)
            tmp=tmp*(((i>>j)&1)?p[j]:1-p[j]);//cout<<"tmp"<<tmp<<endl;
        sum+=tmp;
        for(int j=0;j<n;j++)
            ans[j]+=(((i>>j)&1)?tmp:0);
    }
}
int main()
{
    int n,r,cot=0;
    while(scanf("%d%d",&n,&r),n)
    {
        for(int i=0;i<n;i++)
            scanf("%lf",&p[i]);
        solve(n,r);
        printf("Case %d:\n",++cot);
        for(int i=0;i<n;i++)
            printf("%.6f\n",ans[i]/sum);
    }
    return 0;
}
/*
3 2
0.10
0.20
0.30
5 1
0.10
0.10
0.10
0.10
0.10
*/

4.Double Patience UVA - 1637:

分析:

记忆化搜索+状态压缩。
每个状态对应一个概率,不同状态之间进行转移,以 \(5\) 进制进行状态压缩。
\(cnt\) 没有初始化,找了好久。
代码:

#include<bits/stdc++.h>//记忆化搜索
using namespace std;
const int N=2e6;
const int maxn=1953125;//状态总数5^9
double ans[N];
int power[12];
char card[10][5];
void init()
{
    power[0]=1;
    for(int i=1;i<=9;i++)
        power[i]=power[i-1]*5;
}
double dfs(int n)
{
    if(ans[n]>=0)
        return ans[n];
    int a[10]={0},m=n,t=0;
    ans[n]=0;
    while(m)//转化为5进制的状态表示数
    {
        a[t++]=m%5;
        m/=5;
    }
    t=0;
    for(int i=0;i<9;i++)
    {
        if(a[i]==0)
            continue;
        for(int j=i+1;j<9;j++)
        {
            if(a[j]==0)
                continue;
            if(card[i][a[i]-1]==card[j][a[j]-1])
            {
                t++;
                ans[n]+=dfs(n-power[i]-power[j]);
            }
        }
    }
    if(t==0)//没有状态可以转移
        return (ans[n]=0);
    else
        return (ans[n]/=t);
}
int main()
{
    char ss[5]={0};
    int cnt=0;
    init();
    while(scanf("%s",ss)!=EOF)
    {
        cnt=0;
        card[cnt/4][cnt%4]=ss[0];
        cnt++;
        while(cnt<36)
        {
            scanf("%s",ss);
            card[cnt/4][cnt%4]=ss[0];//cout<<ss[0]<<endl;
            cnt++;
        }
        memset(ans,-1,sizeof(ans));
        ans[0]=1;
        printf("%.6f\n",dfs(maxn-1));
    }
    return 0;
}
/*
AS 9S 6C KS
JC QH AC KH
7S QD JD KD
QS TS JS 9H
6D TD AD 8S
QC TH KC 8D
8C 9D TC 7C
9C 7H JH 7D
8H 6S AH 6H
*/

5.Tribles UVA - 11021

题意:

\(k\) 只麻球,每只只活一天,临死之前可能会出生一些新的麻球,具体出生 \(i\) 个麻球的概率为 \(P_i\),给定 \(m\),求 \(m\) 天后麻球全部死亡的概率。

分析:

因为每只麻球的情况都是一样的,因此只对一只麻球讨论,然后求结果的 \(k\) 次方即可。
\(f[i]\) 表示一只麻球 \(i\) 天内死亡的概率,有:\(f[i]=p[0]+p[1]*f[i-1]+p[2]*f[i-1]^2+...\)
从后向前递推。

代码:

#include <bits/stdc++.h>
using namespace std;
double p[1010],f[1010];
int main()
{
    int t,n,m,k,cas=0;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d%d",&n,&k,&m);
        for(int i=0;i<n;i++)
            scanf("%lf",&p[i]);
        f[0]=0;
        f[1]=p[0];
        for(int i=2;i<=m;i++)
        {
            f[i]=0;
            for(int j=0;j<n;j++)
                f[i]+=p[j]*pow(f[i-1],j);
        }
        printf("Case #%d: %.7f\n",++cas,pow(f[m],k));
    }
    return 0;
}

posted @ 2020-03-31 12:13  xzx9  阅读(607)  评论(0编辑  收藏  举报