您的位置:首页 > 其它

[fzu 2282]置换不动点大于等于k的排列数

2017-07-23 15:29 381 查看
题目链接:http://acm.fzu.edu.cn/problem.php?pid=2282

编号1~n的置换,不动点个数大于等于k的方案数。

参考百度百科错排公式,可以知道长度为n,每个数都不在自己位置的方案数。然后枚举长度即可。

考虑对立面(即小于k个在自己位置的)可以优化空间。

#include<cstdio>
#include<algorithm>
using namespace std;

const int maxn=10005;
const int md=1000000007;
int D[maxn];
int C[maxn][105];
int F[maxn];

int main()
{
D[0]=1;
D[1]=0;
D[2]=1;
for (int i=3;i<=10000;i++)
{
D[i]=1ll*(i-1)*(0ll+D[i-1]+D[i-2])%md;
}
C[0][0]=1;
for (int i=1;i<=10000;i++)
{
C[i][0]=1;
for (int j=1;j<=min(100,i);j++)
{
C[i][j]=(C[i-1][j-1]+C[i-1][j])%md;
}
}
F[0]=1;
for (int i=1;i<=10000;i++)
{
F[i]=1ll*F[i-1]*i%md;
}
int t;
scanf("%d",&t);
while (t--)
{
int n,k;
scanf("%d%d",&n,&k);
int ans=F
;
for (int i=0;i<k;i++)
{
ans=(ans-1ll*C
[i]*D[n-i]%md+md)%md;
}
printf("%d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐