题意:给n个数字,求至少k个数字位置不变的排列数量。
思路:求至少k个人位置不变只要用全排列的数量减掉0-k错排的数量即可
错排公式:Dn = (n-1)*(Dn-2+Dn-1);
错排的数量为C(n,i)*Dn;
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
typedef long long ll;
const int mod = 1e9+7;
const int maxn = 10010;
ll dp[maxn];
ll c[maxn][105];
int main()
{
for(int i = 0; i < maxn; i++)
{
for(int j = 0; j <= min(i,105); j++)
{
if(j==0)
c[i][j] = 1;
else
c[i][j] = (c[i-1][j]+c[i-1][j-1])%mod;
}
}
dp[0] = 1;
dp[1] = 0;
for(int i = 1; i < maxn; i++)
dp[i] = ((i-1)*(dp[i-2]+dp[i-1])+mod)%mod;
int T;
cin >> T;
while(T--)
{
int n,k;
cin >> n >> k;
ll sum = 0;
ll ans = 1;
for(int i = 1; i <= n; i++)
{
ans = (ans*i)%mod;
}
for(int i = 0; i < k; i++)
{
sum = (sum+dp[n-i]*c[n][i])%mod;
}
cout<<(ans-sum+mod)%mod<<endl;
}
return 0;
}