题目:快递小哥每天都幸苦的送快递,今天他需要送N份快递给N个收件人,第i份快递需要送给第i个收件人,请问其中发生恰好k个送错了的情况数是多少?
输入:多样例,每行两数N和K,1<<N<<1000,0<<K<<N,两个都为0结束,该样例无需处理。
输出:每行输出一个结果,因为数值会比较大,因此所有结果需要对10^9+7取模.
分析:水题
1、使用错排公式算出恰好K个排错的种数,预处理成数组。
2、从N个中取出K个有C(N,K)种。
3、C(N,K)和F[K]相乘为最终结果。
代码:
#include<iostream>
using namespace std;
__int64 f[1005];
void Init()
{
f[0]=0;
f[1]=0;
f[2]=1;
for(int i=3;i<=1001;i++)
f[i]=((i-1)*((f[i-1]+f[i-2])%1000000007))%1000000007;
}
__int64 CNK(int n,int k)
{
__int64 a,b;
int i;
a=b=1;
for(i=k+1;i<=n;i++)
a*=i;
for(i=2;i<=n-k;i++)
b*=i;
return a/b;
}
int main()
{
int n,k;
Init();
while(cin>>n>>k && (n||k))
{
printf("%I64d\n",(CNK(n,k)*f[k])%1000000007);
}
return 0;
}原文地址:http://blog.csdn.net/a809146548/article/details/45026485