朋友的礼物(英雄会,csdn,高校俱乐部)信封问题,匹配模型
前言: 首先这是一题解,但是重点最代码之后,有耐心的可以直接从代码后看。
上题目:n个人,每个人都有一件礼物想送给他人,他们决定把礼物混在一起,然后每个人随机拿走一件,问恰好有m个人拿到的礼物恰好是自己的概率是多少? 输出结果四舍五入,保留8位小数,为了保证精度,我们用字符串作为返回类型。
输入:n,m (0<n<100, 0<=m<=n) 例如: n = 2,m = 1,输出:0.00000000; n = 99,m = 0,输出:0.36787944
上代码:
*******************************************************************************/
/* OS : 3.2.0-58-generic #88-Ubuntu SMP Tue Dec 3 UTC 2013 GNU/Linux
* Compiler : g++ (GCC) 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)
* Encoding : UTF8
* Date :
* All Rights Reserved by yaolong.
*****************************************************************************/
/* Description: ***************************************************************
*****************************************************************************/
/* Analysis: ******************************************************************
*****************************************************************************/
/*****************************************************************************/
//*
#include <stdio.h>
#include <iostream>
#include <string> using namespace std;
double jcf(int r){ //计算 1/r! ;
double res=1;
for(int i=1;i<=r;i++){ res*=i;
}
return 1/res; }
class Test {
public: static string calculate (int n,int m)
{
double r_=jcf(m);
double res=0;
for(int i=0;i<=n-m;i++){
if(i%2==1)
res-=jcf(i);
else{
res+=jcf(i);
}
}
res=res*r_;
string tmp;
res=res*100000000;
int tot=(int)(res+0.5);
int k=8;
while(k--){
tmp.insert(0,1,tot%10+'0');
tot/=10;
}
tmp.insert(0,1,'.');
tmp.insert(0,1,'0');
return tmp;
}
};
//start 提示:自动阅卷起始唯一标识,请勿删除或增加。
int main() {
cout<< Test::calculate(36,3)<<endl;
cout<< Test::calculate(12,6);
cout<<endl;
cout<<Test::calculate(99,0)<<endl;
}
//end //提示:自动阅卷结束唯一标识,请勿删除或增加。
本文将以此题引出并解释一下这种匹配问题。
比如 N个信封N封信,k个匹配正确的概率,方法等等。
还有各种变还说法,比如本题的 N个人N份礼物,k个正确的概率。
还有一堆新郎和新娘,k个人选对自己的新娘的组合数等的功能。
这种问题,都源于信封匹配啦。当然这种博文多的是,我也只是在前人的基础上去理解以及解释。
1.先看错位排列的问题。即k=0的情况。
m个朋友,0个人拿对自己的礼物。
我们假设编号从1 到 m,从1号开始拿礼物,这时候1号有m-1个选择,
假设 1号拿到k号的礼物,
1.k如果拿到1的礼物,那么问题就归结到m-2个人的问题,
2.如果k没有拿到1的礼物,则k可以看做是1(因为k不拿1的礼物),问题归结到m-1的问题。
即得到递推式子: A_m = (m-1)*(A_m-1 + A_m-2)用习惯的数列表示就是
A_n = (n-1)*(A_n-1 + A_n-2);
显然A_1 =0 ,A_2 =1(一个人的时候为0,二个人的时候是1.)
解这种数列的通向公式方法不算少,最基本的一个解法就是用高中的数列手段啦。
A_n -n* A_n-1 = - [ A_n-1 - (n-1) * A_n-2 ]
即有
[ A_n - n* A_n-1 ]/[ A_n-1 - (n-1) * A_n-2 ]=-1;
记B_n=[A_n- n* A_n-1 ,累乘一下,B_n=(-1)^(n-2) * B_2=(-1)^n (n>=2);
即有
A_n- n*A_n-1 = (-1)^n;
A_n / (-1)^n = - n * A_n-1 /(-1)^(n-1) +1;
记C_n= A_n / (-1)^n ,即解C_n = - n* C_n-1 +1;
求解这个数列,也是高中的数列方法了,C_n= f(n) *C_n-1 +C;
构造h(n),使得f(n)=h(n-1)/h(n) ,之后转换成 h(n)*C_n = h(n-1)*C_n-1 +C*h(n) ,累加求解就可以了。
对于n显然构造的是 h(n)=1/n!;(为什么?我能说是经验吗?)
之后,这个累加过程我就不写了,最后给出华丽丽的公式:
A_n= n!*[1-1/1!+1/2!-1/3!+1/4!-…+(-1)^n*1/n!]
而全排列是n! ,所以概率则为 P(n)=A_n/n! =1-1/1!+1/2!-1/3!+1/4!-…+(-1)^n*1/n!
2.m个人拿对(m!=0)的时候
有了上一步的支持,这个就异常的简单,则C(n,m)*A_n-m 即可
即 F(n,m) = C(n,m)*(n-m)!*[1-1/1!+1/2!-1/3!+1/4!-…+(-1)^(n-m)*1/(n-m)!]
P(n,m) = F(n,m)/n!=(1/m! )*[1-1/1!+1/2!-1/3!+1/4!-…+(-1)^(n-m)*1/(n-m)!]
3.对应 英雄会的朋友的礼物,就是套用2的公式,so easy(之前我也看过其他博文写的这题,但是文字太多,看得有点烦。)
朋友的礼物(英雄会,csdn,高校俱乐部)信封问题,匹配模型的更多相关文章
- P次方数 英雄会 csdn 高校俱乐部
题目: 一个整数N,|N| >= 2, 如果存在整数x,使得N = x * x * x... (p个x相乘) =x^p,则称N是p次方数,给定32位内的整数N,求最大的P.例如N=5,输出1,N ...
- CSDN 高校俱乐部: 排列搜索
CSDN 高校俱乐部/英雄会 题目: 设数组a包含n个元素恰好是0..n - 1的一个排列,给定b[0],b[1],b[2],b[3]问有多少个0..n-1的排列a,满足(a[a[b[0]]]*b[0 ...
- CSDN高校俱乐部2013年秋季北京地区第一站“编程语言的应用及其发展”—北京联合大学
2013年12月11日晚17:00.CSDN高校俱乐2013年秋季北京地区第一站“编程语言的应用及其发展”在北京联合大学进行. 首先,CSDN总部人员介绍CSDN俱乐部的改版以及线上编程挑战赛.CSD ...
- (csdn高校俱乐部编程挑战)2的补码
题目详情 在计算机中,整数是以2的补码的形式给出的. 给出整数A和B,如果计算机是32位机.求从A到B之间的全部二进制数中,一共用了多少个1. 输入格式: 多组数据,每组数据一行,由两个整数A,B, ...
- CSDN高校俱乐部第二届战神杯第二题题解
两个人玩一个数字游戏,给定两个正整数A,B,两个人轮流从一个数中减去另外一个数的正数倍.要保证结果非负, 首先得到0的人获胜. 比如:30 8经过一步操作能够变为22 8 或者14 8 或者 6 8. ...
- N的N次方(高校俱乐部)
最近一直在刷字符串和线段树,也越来越少玩高校俱乐部,无聊看到一题N的N次方的问题,脑海中各种打表就涌现出来了. 弄了不一会儿,就写完了,马上提交,但是系统好像出了问题,提示"哦哦,出了点状况 ...
- 翻纸牌 高校俱乐部 英雄会 csdn
题目描述 有一种纸牌游戏,很有意思,给你N张纸牌,一字排开,纸牌有正反两面,开始的纸牌可能是一种乱的状态(有些朝正,有些朝反),现在你需要整理这些纸牌.但是麻烦的是,每当你翻一张纸牌(由正翻到反,或者 ...
- 半质数的个数 csdn 英雄会 高校俱乐部
2·14 情人&元宵节专题:半质数的个数. 题目:质数是大家熟知的概念,我们定义一个半质数的概念:如果一个数恰好是两个质数的乘积(可以相同),则称它为半质数.前几个半质数是 4, 6, 9, ...
- 大学生程序猿IT情书“2014爱的告白挑战赛”获奖名单及优秀情书展示系列之 - 【IT术语】情书+【搞笑另类】情书
经过专家评委们的层层精心评选和认真讨论,恭喜下面同学终于入选CSDN高校俱乐部"大学生程序猿IT情书2014爱的告白挑战赛活动"优胜者名单.获奖者将在本周内收到邮件通知.请依照邮件 ...
随机推荐
- (转载)利用burp suite截断上传拿shell
burpsuite上传必须要有filepath这个参数 第一步:选择一个jpg后缀的马. 第二步:设置本地代理,burp的本地端口是8080 第三步:打开burp suite 按图操作就ok了. 第四 ...
- javascrip中array使用
一.测试数组长度是使用arr.length;(注:使用delete不会修改数组的length属性) 二.数组方法 1.join() Array.join()方法将数组所有元素都转化为字符串连接在一起, ...
- 神经网络中误差反向传播(back propagation)算法的工作原理
注意:版权所有,转载需注明出处. 神经网络,从大学时候就知道,后面上课的时候老师也讲过,但是感觉从来没有真正掌握,总是似是而非,比较模糊,好像懂,其实并不懂. 在开始推导之前,需要先做一些准备工作,推 ...
- struts1与strut2的区别
struts1和struts2是两个完全不同的框架 struts1工作流程:发布Struts Web服务时,根据web.xml初始化ActionServlet,ActionContext等内容.在接到 ...
- 在Mybatis-spring中由于默认Autowired导致不能配置多个数据源的问题分析及解决
在使用Mybatis中,通常使用接口来表示一个Sql Mapper的接口以及相对应的xml实现,而在spring的配置文件中,通常会使用MapperScannerConfigurer来达到批量扫描以及 ...
- 【原创】javascript——prototype与__proto__
一定要注意这个概念:javascript世界里,万物皆对象, function是对象,prototyp也是对象. 新建构造函数,并实例 var Person = function(){} var ...
- Android 获取手机总内存和可用内存等信息
在android开发中,有时候我们想获取手机的一些硬件信息,比如android手机的总内存和可用内存大小.这个该如何实现呢? 通过读取文件"/proc/meminfo"的信息能够获 ...
- java代理
首先,java中为什么要提出代理的设计模式呢?代理模式的作用是:为其它对象提供一种代理以控制对这个对象的訪问.在某些情况下,一个客户不想或者不能直接引用还有一个对象,而代理对象能够在client和目标 ...
- 使用like时left outer join和inner join的区别
--select top 10000 * into #s from search set statistics time on set statistics io on select userId,c ...
- MapReduce中的Join算法
在关系型数据库中Join是非常常见的操作,各种优化手段已经到了极致.在海量数据的环境下,不可避免的也会碰到这种类型的需求,例如在数据分析时需要从不同的数据源中获取数据.不同于传统的单机模式,在分布式存 ...