【组合数学:第一类斯特林数】【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 ...
随机推荐
- File类的使用
java.io.File 类用于表示文件(目录) File类只用于表示文件(目录)的信息(名称.大小等),不能用于文件内容的访问 file类常用的api package com.zhb.java; i ...
- struts2必需jar包
asm-3.3.jar commons-logging-1.1.3.jarasm-commons-3.3.jar freemarker-2.3. ...
- JavaScript --------------继前面继承方式-------总结
创建对象方式: 工厂模式:使用简单的函数创建对象,为对象添加属性和方法,然后返回对象: function createPerson(name,age,job){ var o = new Object( ...
- 探究foreach对于迭代变量的封装性的研究
众所周知教科书上对于foreach之中的注释是在遍历过程中无法改变其遍历的元素例如声明一个数组 ,,,}; foreach(int m in ii){ m = ;//错误 “m”是一个“foreach ...
- Android Canvas设置绘画时重叠部分的处理模式【含效果图】
在Android的PorterDuff.Mode类中列举了他们制定的规则: android.graphics.PorterDuff.Mode.SRC:只绘制源图像 android.graphics.P ...
- Unity轻量级依赖注入容器
一.前言 Unity是一个轻量级的可扩展的依赖注入容器,支持构造函数,属性和方法调用注入.在Nuget里安装unity
- 表单提交---前端页面模拟表单提交(form)
有些时候我们的前端页面总没有<form></form>表单,但是具体的业务时,我们又必须用表单提交才能达到我们想要的结果,LZ最近做了一些关于导出的一些功能,需要调用浏览器默认 ...
- git操作流程
- XML巩固
一.XML基础 1.XML区分大小写, 2.XML属性值必须有引号(单引双引均可) 3.XML必须有根元素 4.一些特殊字符的需要用实体引用来替换 < < 小于 > > 大于 ...
- mac下 WebStorm下主题包安装
mac下: 主题包 1.mac下,点击桌面,使用shift+command+G 输入:~/Library/Preferences 前往(mac查找安装目录的方法,因为默认这些文件夹是隐藏的),进入We ...