标签:排列 斯特林 左边 HDU4372 每组 第一类 元素 最高 LL
题意:N座高楼,高度均不同且为1~N中的数,从前向后看能看到F个,从后向前看能看到B个,问有多少种可能的排列数。
0 < N, F, B <= 2000
首先我们知道一个结论:n的环排列的个数与n-1个元素的排列的个数相等,因为P(n,n)/n=(n-1)!。
可以肯定,无论从最左边还是从最右边看,最高的那个楼一定是可以看到的.
假设最高的楼的位置固定,最高楼的编号为n,那么我们为了满足条件,可以在楼n的左边分x-1组,右边分y-1组,且用每
组最高的那个元素代表这一组,那么楼n的左边,从左到右,组与组之间最高的元素一定是单调递增的,且每组中的最高元
素一定排在该组的最左边,每组中的其它元素可以任意排列(相当于这个组中所有元素的环排列)。右边反之亦然。
然后,可以这样考虑这个问题,最高的那个楼左边一定有x-1个组,右边一定有y-1个组,且每组是一个环排列,这就引出
了第一类Stirling数(n个人分成k组,每组内再按特定顺序围圈的分组方法的数目)。
我们可以先把n-1个元素分成x-1+y-1组,然后每组内部做环排列。再在所有组中选取x-1组放到楼n的左边。所以答案是
ans(n, f, b) = C[f + b - 2][f - 1] * S[n - 1][f + b - 2];
#include <iostream> #include <string.h> #include <stdio.h> using namespace std; typedef long long LL; const int N=2005; const LL MOD=1000000007; LL C[N][N]; LL S[N][N]; void Init() { int i,j; for(i=0;i<N;i++) { C[i][0]=1; C[i][i]=1; S[i][0]=0; S[i][i]=1; for(j=1;j<i;j++) { C[i][j]=(C[i-1][j]%MOD+C[i-1][j-1]%MOD)%MOD; S[i][j]=((i-1)%MOD*S[i-1][j]%MOD+S[i-1][j-1]%MOD); } } } int main() { LL t,n,f,b,ans; Init(); scanf("%I64d",&t); while(t--) { scanf("%I64d%I64d%I64d",&n,&f,&b); ans=C[f+b-2][f-1]%MOD*S[n-1][f+b-2]%MOD; printf("%I64d\n",ans); } return 0; } 原文链接:https://blog.csdn.net/ACdreamers/article/details/9732431
标签:排列,斯特林,左边,HDU4372,每组,第一类,元素,最高,LL
来源: https://www.cnblogs.com/cutemush/p/11908349.html
本站声明:
1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。