【JZOJ 3871】 无聊的游戏

37 篇文章 0 订阅
17 篇文章 0 订阅

Description

学校的运动会开始了,体能很菜的小可可没报任何比赛项目,于是和同学们玩一个十分无聊的游戏。
游戏在一个由n*n个方格组成的正方形棋盘上进行,首先在每个方格上均匀随机地填入1到m之间的正整数(每个方格填的数均不同),然后小可可均匀随机地选出k个1到m的数字(选的数不可重复,可能选的数不在棋盘上),把它们出现在棋盘上的方格涂黑,设有R行被整行涂黑,有C列被整列涂黑,小可可便可以得到2^(R+C)分。
现在小可可想知道他的期望得分是多少,你能帮助他吗?
对于100%的数据,2≤n≤300, n*n≤m≤100000, n≤k≤m。

Analysis

很好的组合数学题,这题我学到了一些思想
每一行列的涂黑与否可以变成二进制
首先这个答案为2^(R+C),等价于一个状态的子集的个数(只能说这一步转化打死我也想不到)
朴素思路即枚举行列状态,计算其子集个数,但这很难算
正难则反
枚举行列状态,计算其作为多少状态的子集
这好算,因为最少要用n(r+c)-rc个点(设为t)才能覆盖出这些行列,这些点的数必选,其余可以选择其他任意点
所以 Cktmt/Ckm 为成功概率p
那么答案即为

i=0nj=0nCinCjnp

枚举行列有多少个被涂黑,那么前两个组合数就是所有可能行列个数。
这东西理解容易,但是自己想到却很难

Code

#include<cstdio>
#include<algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int N=100005;
double n,m,k,ans,c[N],b[N];
int main()
{
    scanf("%lf %lf %lf",&n,&m,&k);
    c[0]=1;
    fo(i,1,n) c[i]=c[i-1]/i*(n-i+1);
    b[0]=1;
    fo(j,1,n*n) b[j]=b[j-1]*(k-j+1)/(m-j+1);
    fo(i,0,n)
        fo(j,0,n)
        {
            int t=n*(i+j)-i*j;
            ans=ans+c[i]*c[j]*b[t];
        }
    if(ans>1e99) printf("%lf",1e99);
    else printf("%lf",ans);
    return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值