《中山大学内部选拔(一)》 游戏

来源:互联网 发布:滨州大数据产业园 编辑:程序博客网 时间:2024/06/06 03:48

【问题描述】

  A,B两人各有不同分值的 M 张牌,他们进行N回合的游戏,每个回合两人分别在自己的M张牌里抽取1张,然后记下各自的分数并把牌收回到自己的牌堆中,然后继续下一回合。游戏结束后,两人的得分就是各自每回合的分值和,如果其中一个人的分数和较大,则这个人就赢得比赛。

  现在告诉你A,B两人各自M张牌的分值以及游戏的回数,请你计算A赢得比赛的概率。

【输入格式】

  首先是T,表示数据组数。
  每组数据包含4行:第1行为M,第2行为A的M张牌的分值,第3行是B的M张牌的分数。第4行为N。

【输出格式】

  输出一个保留6位小数的实数,表示A赢得比赛的概率。

【输入样例】

1
10
5 9 6 12 13 15 52 11 11 11
8 9 6 3 2 1 85 9 2 3
15

【输出样例】

0.620092

【数据范围】

1<=M<=100 0<=N<=50 每张牌的分值不超过50。

【来源】

《中山大学内部选拔(一)》

这道题我拿到的题数据范围有误害的我好一阵乱优化,结果其实直接就能过。
很明显这是一道数学期望,我们可以直接用递推得到2个人分别得到每个分数的概率,这时我们要用一个前缀和的思想,把乙的分数的前缀和算出来,用g(i)表示乙得到小于等于i的分数的概率。然后没举每个i用甲得到分数i的概率乘上g(i-1),全部加起来就是答案了。

详细代码如下:(有点丑,毕竟乱优化了一波)

#include<cstdlib>#include<cstring>#include<cstdio>#include<iostream>#include<vector>#include<algorithm>using namespace std;typedef long long ll;const int maxn=1000005;double d[maxn],q[maxn],g[maxn],p,a1[maxn],b1[maxn];int a[maxn],b[maxn],cnt1,cnt2;int m,n;int main(){    freopen("Game.in","r",stdin);    freopen("Game.out","w",stdout);    int T;    scanf("%d",&T);    while(T--)    {        cnt1=cnt2=1;        scanf("%d",&m);        for(int i=1;i<=m;i++) scanf("%d",&a[i]);        sort(a+1,a+1+m);        for(int i=1;i<=m;i++) scanf("%d",&b[i]);        sort(b+1,b+1+m);        p=1.0/(double)m;        scanf("%d",&n);        memset(d,0,sizeof(d));        memset(a1,0,sizeof(a1));        memset(b1,0,sizeof(b1));        for(int i=2;i<=m;i++)        {            if(a[i]!=a[i-1]) a[++cnt1]=a[i];            else a1[cnt1]+=p;        }        for(int i=1;i<=cnt1;i++) a1[i]+=p,d[a[i]]=a1[i];        for(int i=2;i<=n;i++)        for(int j=a[cnt1]*i;j>=a[1]*(i-1);j--)//算甲前i次得到j分的概率        {            double ans=0;            for(int k=1;k<=cnt1;k++)             {                if(j-a[k]<a[1]*(i-1)) break;                ans+=d[j-a[k]]*a1[k];            }            d[j]=ans;        }        memset(q,0,sizeof(q));        for(int i=2;i<=m;i++)        {            if(b[i]!=b[i-1]) b[++cnt2]=b[i];            else b1[cnt2]+=p;        }        for(int i=1;i<=cnt2;i++) b1[i]+=p,q[b[i]]=b1[i];        for(int i=2;i<=n;i++)        for(int j=b[cnt2]*i;j>=b[1]*(i-1);j--)算乙前i次得到j分的概率        {            double ans=0;            for(int k=1;k<=cnt2;k++)             {                if(j-b[k]<b[1]*(i-1)) break;                ans+=q[j-b[k]]*b1[k];            }            q[j]=ans;        }        memset(g,0,sizeof(g));        int ans2=0;        int t=max(b[cnt2],a[cnt1])*n;        for(int i=b[1]*n;i<=t;i++)//算前缀和g,主要范围        g[i]=g[i-1]+q[i];        double ans=0;        for(int i=a[1]*n;i<=t;i++)//求答案        ans+=g[i-1]*d[i];        printf("%.6lf\n",ans);    }    return 0;}
1 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 8个月婴儿疝气怎么办 头部疤痕不长发怎么办呢 有纹身想去当兵怎么办 在部队干活的钱怎么办 新兵5公里超过标准时间怎么办 17个月婴儿裹手怎么办 7个月婴儿裹手怎么办 俩月孩子裹手怎么办 婴儿 3个月 裹手怎么办 一岁宝宝裹手怎么办 5个月宝宝裹手怎么办 不想让孩子裹手怎么办 四个月宝宝裹手怎么办 开车撞狗了跑了怎么办 母螃蟹抱卵了怎么办 我能怎么办我也想睡觉 一个人的微信群找不到了怎么办 一个人的微信被删了找不到了怎么办 不想回对方微信怎么办 喜欢我的人太多怎么办 假如战争今夜打响我们该怎么办 约客户客户说忙怎么办 第一天来姨妈痛怎么办 痛经痛的很厉害怎么办 工作第一天被辞怎么办 第一天练车紧张怎么办 到新公司第一天怎么办 我妈上班别人欺负怎么办 欺负别人他妈来找了怎么办 家人都欺负我妈怎么办 人老了日不动了怎么办? 日照职业技术学院公租房怎么办留宿 眼镜上沾了胶水怎么办 近视镜片刮花了怎么办 墨镜镜片磨花了怎么办 邻居养狗味道大怎么办 邻居不让养狗了怎么办 养狗地板有味道怎么办 狗狗嘴巴被大狗咬肿了怎么办 花了钱心里难受怎么办 狗在屋里有味道怎么办