【组合数学:第一类斯特林数】【HDU3625】Examining the Rooms
Examining the Rooms
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1138 Accepted Submission(s): 686
one key in each room, and all the possible distributions are of equal possibility. For example, if N = 3, there are 6 possible distributions, the possibility of each is 1/6. For convenience, we number the rooms from 1 to N, and the key for Room 1 is numbered
Key 1, the key for Room 2 is Key 2, etc.
To examine all the rooms, you have to destroy some doors by force. But you don’t want to destroy too many, so you take the following strategy: At first, you have no keys in hand, so you randomly destroy a locked door, get into the room, examine it and fetch
the key in it. Then maybe you can open another room with the new key, examine it and get the second key. Repeat this until you can’t open any new rooms. If there are still rooms un-examined, you have to randomly pick another unopened door to destroy by force,
then repeat the procedure above, until all the rooms are examined.
Now you are only allowed to destroy at most K doors by force. What’s more, there lives a Very Important Person in Room 1. You are not allowed to destroy the doors of Room 1, that is, the only way to examine Room 1 is opening it with the corresponding key. You
want to know what is the possibility of that you can examine all the rooms finally.
3
3 1
3 2
4 2
0.3333
0.6667
0.6250HintSample Explanation When N = 3, there are 6 possible distributions of keys: Room 1 Room 2 Room 3 Destroy Times
#1 Key 1 Key 2 Key 3 Impossible
#2 Key 1 Key 3 Key 2 Impossible
#3 Key 2 Key 1 Key 3 Two
#4 Key 3 Key 2 Key 1 Two
#5 Key 2 Key 3 Key 1 One
#6 Key 3 Key 1 Key 2 One In the first two distributions, because Key 1 is locked in Room 1 itself and you can’t destroy Room 1, it is impossible to open Room 1.
In the third and forth distributions, you have to destroy Room 2 and 3 both. In the last two distributions, you only need to destroy one of Room 2 or Room
递推关系的说明:
考虑第p个物品,p可以单独构成一个非空循环排列,这样前p-1种物品构成k-1个非空循环排列,方法数为s(p-1,k-1);
也可以前p-1种物品构成k个非空循环排列,而第p个物品插入第i个物品的左边,这有(p-1)*s(p-1,k)种方法。
边界条件 s(x,0)=0;s(x,x)=1;
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=20;
long long f[25],stir[25][25];
int solve()
{
int i,j;
f[0]=1;
for(i=1;i<=maxn;i++)
f[i]=i*f[i-1];
//因为N有N!种排列顺序,这作为总数
//计算概率
for(i=1;i<=maxn;i++)
stir[i][0]=0;
stir[1][1]=1;
for(i=1;i<=maxn;i++)
for(j=1;j<=i;j++)
{
if(i==j)
stir[i][j]=1;
else
stir[i][j]=stir[i-1][j-1]+(i-1)*stir[i-1][j];
}
for(i=1;i<=maxn;i++)
for(j=1;j<=maxn;j++)
if(stir[i][j]<0)
stir[i][j]=-stir[i][j];
return 0;
}
int main()
{
int cas,n,i,k;
long long sum;
solve();
scanf("%d",&cas);
while(cas--)
{
scanf("%d %d",&n,&k);
sum=0;
for(i=1;i<=k;i++)
sum+=stir[n][i]-stir[n-1][i-1];
printf("%.4lf\n",1.0*sum/f[n]);
//因为写成printf("%.4lf\n",(double)sum/f[n]);
//run time error! 下次一定记好了!
}
return 0;
}
接下来是我的方法!
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <ctime>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#define oo 0x13131313
using namespace std;
long long H[21];
long long F[21][21];
long long T[21];
long long C[21][21];
void CLT(int n,int len)
{
long long tot=n;
long long k=1;
for(int i=1;i<=len;i++)
{
if(T[i]==1)
{
k*=C[tot-1][1];
tot-=T[i];
}
else
{
k*=(C[tot][T[i]]*H[T[i]-1]);
tot-=T[i];
}
}
tot=1;
T[len+1]=0;
for(int i=2;i<=len+1;i++)
{
if(T[i]==T[i-1])
{
tot++;
}
else
{
k=k/H[tot];
tot=1;
}
}
F[n][len]+=k;
}
int getxulie(int n,long long tot,int prev,int len,int deep)
{
T[deep]=prev;
tot+=prev;
if(deep==len)
if(tot==n)
{
CLT(n,len);
return 1;
}
else
return 0;
for(int i=prev;i<=n-len+1;i++)
getxulie(n,tot,i,len,deep+1);
return 0;
}
void YCLYCL()
{
H[0]=1;
for(int i=1;i<=20;i++)
{
H[i]=H[i-1]*i;
}
for(int i=1;i<=20;i++)
C[i][0]=1;
C[1][1]=1;
for(int i=2;i<=20;i++)
for(int j=1;j<=i;j++)
{
C[i][j]=C[i-1][j-1]+C[i-1][j];
}
}
void YCL()
{ YCLYCL();
for(int i=2;i<=20;i++)
for(int j=1;j<=i;j++)
{
for(int k=1;k<=i-j+1;k++)
{
memset(T,0,sizeof(T));
getxulie(i,0,k,j,1);
}
}
for(int i=2;i<=20;i++)
for(int j=1;j<=i;j++)
{
F[i][j]+=F[i][j-1];
}
}
void inin()
{
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
}
int main()
{
//inin();
YCL();
int K;
cin>>K;
int a;int b;
while(K--)
{
cin>>a>>b;
printf("%.4lf\n",((double)F[a][b]/(double)H[a]));
}
}
【组合数学:第一类斯特林数】【HDU3625】Examining the Rooms的更多相关文章
- [HDU 3625]Examining the Rooms (第一类斯特林数)
[HDU 3625]Examining the Rooms (第一类斯特林数) 题面 有n个房间,每个房间有一个钥匙,钥匙等概率的出现在n个房间内,每个房间中只会出现且仅出现一个钥匙.你能炸开门k次, ...
- hdu 3625 Examining the Rooms —— 第一类斯特林数
题目:http://acm.hdu.edu.cn/showproblem.php?pid=3625 学习斯特林数:https://blog.csdn.net/qq_33229466/article/d ...
- HDU3625(SummerTrainingDay05-N 第一类斯特林数)
Examining the Rooms Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
- 【Luogu4609】建筑师(第一类斯特林数,组合数学)
[Luogu4609]建筑师(组合数学) 题面 洛谷 题解 首先发现整个数组一定被最高值切成左右两半,因此除去最高值之后在左右分开考虑. 考虑一个暴力\(dp\) ,设\(f[i][j]\)表示用了\ ...
- HDU 4372 Count the Buildings——第一类斯特林数
题目大意:n幢楼,从左边能看见f幢楼,右边能看见b幢楼 楼高是1~n的排列. 问楼的可能情况 把握看到楼的本质! 最高的一定能看见! 计数问题要向组合数学或者dp靠拢.但是这个题询问又很多,难以dp ...
- 【HDU 4372】 Count the Buildings (第一类斯特林数)
Count the Buildings Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Othe ...
- 如何快速求解第一类斯特林数--nlog^2n + nlogn
目录 参考资料 前言 暴力 nlog^2n的做法 nlogn的做法 代码 参考资料 百度百科 斯特林数 学习笔记-by zhouzhendong 前言 首先是因为这道题,才去研究了这个玩意:[2019 ...
- 【2019雅礼集训】【CF 960G】【第一类斯特林数】【NTT&多项式】permutation
目录 题意 输入格式 输出格式 思路 代码 题意 找有多少个长度为n的排列,使得从左往右数,有a个元素比之前的所有数字都大,从右往左数,有b个元素比之后的所有数字都大. n<=2*10^5,a, ...
- CF960G Bandit Blues 第一类斯特林数、NTT、分治/倍增
传送门 弱化版:FJOI2016 建筑师 由上面一题得到我们需要求的是\(\begin{bmatrix} N - 1 \\ A + B - 2 \end{bmatrix} \times \binom ...
随机推荐
- boost::asio 的同、异步方式
转自:http://blog.csdn.net/zhuky/archive/2010/03/10/5364574.aspx Boost.Asio是一个跨平台的网络及底层IO的C++编程库,它使用现代C ...
- VS2008下编译boost_1_47_0
1,boost下载 如果不想自己编译,可下载http://boostpro.com/download/boost_1_47_setup.exe,安装后,程序会提供选项供下载已经编译好的库文件,基于 ...
- TortoiseSVN和VisualSVN-下载地址
isualSVN的下载地址http://www.visualsvn.com/visualsvn/ 它可以以插件的形式嵌入到visual studio里面,让团队协作更轻松,最新的版本已经支持Visua ...
- PowerDesigner中在生成的数据库脚本中用name列替换comment列作为字段描述的方法
1 PowerDesigner中在生成的数据库脚本中用name列替换comment列作为字段描述的方法如下, 依次打开Tools -- Execute Commands -- Run Script,运 ...
- linux环境下编码的问题
查看linux支持的编码格式: locale -a查看文件的编码格式: :set fileencodinglinux下文本编码转换: iconv -f gbk -t utf8 main.cpp > ...
- MFC让控件随窗口大小而改变
转载自http://blog.csdn.net/chw1989/article/details/7488711 大小和位置都改变(亲测可行) 1.首先为窗体类添加CRect m_rect,该成员变量用 ...
- JS 混淆加密
http://www.javascriptobfuscator.com/Javascript-Obfuscator.aspx http://www.javascriptobfuscator.com/d ...
- CI(CodeIgniter)学习第一讲
一.CI的优势一. (1).CI是一个PHP框架:大家都知道PHP框架有很多,CI只是其中之一,框架是为了重用发明的.同样,CI的目标是实现让你比从零开始编写代码更快速地开发项目.CI可以将需要完成的 ...
- 查文件大小列表 MySQL问题
du -sh /* | sort -nr 打开网站发现Too many connections The server quit without updating PID file (/usr/loca ...
- nginx之依据IP做限制
环境如下: [root@localhost ~]# cat /etc/issueCentOS release 6.5 (Final)Kernel \r on an \m[root@localhost ...