班级大讨论——论英语七选五

前言

在2017年9月的某一节晚自习上课前,NEYC 1702班不知为什么开始了一个自发的“班级大讨论”,班级中的很多同学都在“埋头苦算”,也有一些同学在争论着一些什么。这次讨论的核心话题便是英语开始中的一种题型“七选五”问题。这次有着班级大半部分同学参与进来的讨论,在很多方面都有着或多或少的指导意义。

序幕

A君:“…英语七选五我总是选不准,我真是太垃圾了。”
B君:“实在不行那就得蒙啊,说不定蒙的比选的得分还多呢!”
……

A君:“真的吗?那你怎么能证明蒙的比选的得分多呢?”
B君:“那咱们就试试呗,我心里想一组答案,你蒙一组答案,看看能得多少分。”
……

A君:“EFGAB!”
B君:“可惜料了,我想的是ABCDE @%$#^..”
……

他们来回猜了好多次,但只有少数的情况“得了分”,大多数时候都是零分。

A君:“原来瞎猜的得分概率那么低啊..诶?那你觉得如果我们瞎猜,不“暴零”的概率又是多少呢?”
B君陷入了沉思。
……

问题1:

随机生成一个回答序列,A[1..5]满足 A[i]属于{A,B,C,D,E,F,G}(1<=i<=5)并且有A[i]!=A[j] (i!=j 且 1<=i,j<=5 )(这是这个问题的难点,因为七选五就算是瞎蒙,也不会有人去蒙重复的选项!)。这个问题的答案序列B[1..5]是一个唯一确定的序列,而且也满足这两条性质。当且仅当存在A[i]=B[i] (1<=i<=5),我们说这道题没有“暴零”。求这道题不“暴零”的概率是多少。

GGN给出的解决方案:

组合数 + 容斥原理。

不暴零的方案数 = 至少对一道题的方案数 - 至少对两道题的方案数 + 至少对三道题的方案数 -至少对四道题的方案数 + 五道题都对的方案数

记至少对i道题的方案数为f(i),即:

E = f(1) - f(2) + f(3) - f(4) +f(5)

再看f(i):

至少i道题正确的方案数相当于是在从5个位置选出i个作为“正确的位”的情况下剩下5-i个位置从剩下7-i个字母里任意选的方案数,即:

f(i) = C(5,i) * P(7-i,5-i)

这样就可求出E。

总方案数很显然等于P(7,5),除一下就可以得到答案。

GGN的程序解决

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;

const int maxn=20;
int dpc[maxn][maxn];  //储存组合数
int vis[maxn][maxn]; //记忆化搜索标记 

int C(int n,int m)   //记忆化搜索 
{
    if(vis[n][m])
        return dpc[n][m];
    vis[n][m]=1;
    if(m==n || m==0)dpc[n][m]=1;
    else if(n<m)dpc[n][m]=0;
    else dpc[n][m]=C(n-1,m-1)+C(n-1,m);
    return dpc[n][m];
}

int P(int n,int m) //暴力求排列 
{
    int ans=1;
    for(int i=1;i<=m;i++)
        ans*=(n-i+1);
    return ans;
}

int f(int i) //至少对i道题的方案数 
{
    return C(5,i) * P(7-i,5-i);
}

int E() //计算有得分的方案数 
{
    int ans=0;
    for(int i=1;i<=5;i++)
        if(i&1)
            ans+=f(i);
        else ans-=f(i);
    return ans;
}

int main()
{
    cout<<"Method 1 "<<endl;
    cout<<"E = "<<E()<<", all = "<<P(7,5)<<endl;
    cout<<"P = "<<(double)E()/P(7,5)<<endl;
    return 0;
}

这个程序的运行结果如下:

利用组合数解决的效果

为了证明这个程序的正确性,写个暴力检验一下也是必不可少的:

#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;

int A[6],B[6]={-1,1,2,3,4,5}; //两个序列 1~7 表示七个选项 
int vis[8]; 
int Cnt=0; //得分方案数 

void DFS(int step) //暴力搜索 
{
    if(step>5) //得到一个解 
    {
        for(int i=1;i<=5;i++) //判断是否暴零 
            if(A[i]==B[i])
            {
                Cnt++;break;
            }
        return;
    }
    for(int i=1;i<=7;i++) //枚举选项 
    {
        if(!vis[i])
        {
            vis[i]=1;
            A[step]=i;
            DFS(step+1);
            vis[i]=0;
        }
    }
}

int main()
{
    cout<<"Method 2"<<endl;
    DFS(1); //暴搜
    cout<<"E = "<<Cnt<<" all = "<<2520<<endl;
    cout<<"P = "<<(double)Cnt/2520<<endl; 
    return 0;
}

这个程序的运行效果如下:

这是暴力法解决的效果

发现得到了完全相同的答案,GGN很开心!这道题据HJQ大佬说还有一种DP的方法,不过我暂时还没有学会,所以没写在这里。

小结1

不难发现,当你在做七选五的时候,如果你乱蒙,你有52%的概率不得零分。大概就是一半的概率呗。但是你也别高兴得太早…

问题2

按照问题1的规则,如果我们定义一个回答的得分为

(A[i]==B[i])

求随机选的得分期望是多少。

这道题好像后来没有人试着用数学方法去解,不过我试着写了个暴力..

#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;

int A[6],B[6]={-1,1,2,3,4,5}; //两个序列 1~7 表示七个选项 
int vis[8]; 
int Cnt[6]; //统计每一种得分的方案数 

void DFS(int step) //暴力搜索 
{
    if(step>5) //得到一个解 
    {
        int ans=0;
        for(int i=1;i<=5;i++) //计算得分 
            if(A[i]==B[i])
                ans++;
        Cnt[ans]++; //方案数++ 
        return;
    }
    for(int i=1;i<=7;i++) //枚举选项 
    {
        if(!vis[i])
        {
            vis[i]=1;
            A[step]=i;
            DFS(step+1);
            vis[i]=0;
        }
    }
}

void output(double x) //输出柱状图 
{
    for(int i=1;i<=x;i++)
        printf("█"); //稍微有点简陋凑合看吧
    double delta=x-int(x);
    if(delta>=0.8)
        printf("▉");
    else if(delta>=0.7)
        printf("▊");
    else if(delta>=0.6)
        printf("▋");
    else if(delta>=0.5)
        printf("▌");
    else if(delta>=0.4)
        printf("▍");
    else if(delta>=0.2)
        printf("▎");
    else printf("▏");
}

int main()
{
    cout<<"Question 2"<<endl;
    DFS(1); //暴搜
    long long score_sum=0;
    for(int i=0;i<=5;i++)
    {
        printf("Score =%3d:%5d ",i,Cnt[i]);
        output((double)Cnt[i]/50.0);
        printf("\n");
        score_sum+=Cnt[i]*i;
    }
    printf("Ex = %lf\n",(double)score_sum/2520);
    return 0;
}

这个程序的运行结果:

得分柱状图

由此可见,七选五随便选得分的期望只有0.7分,连一分都不到。

(由此观之,王之蔽甚矣)

结论

英语七选五,还是认认真真答吧,想靠蒙得分,没戏…

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值