题目:快递小哥每天都幸苦的送快递,今天他需要送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