H.Permutation | |||||
| |||||
Description | |||||
n个人排成一队,队头的人编号为1,后面的人编号分别为2,3,…,n. 1号人前面没有人,i号人的前面是i-1。 现在Kim想让这n个人重新排队,要求重新排队后编号为i的人前面不能是i-1。问有多少种排队的方法。方案数可能很大,输出答案模1e9+7。 | |||||
Input | |||||
第一行一个整数T,表示有T组数据。 接下来T行,每行一个整数n。表示有n个人排成一队。 | |||||
Output | |||||
对于每个n,输出答案 mod 1000000007。 | |||||
Sample Input | |||||
2
1
4
| |||||
Sample Output | |||||
1
11
| |||||
Hint | |||||
T<=2000 n<=2000000 n=4 时,原队列为 1 2 3 4。所有合法的新队列如下: 4 1 3 2 4 3 2 1 4 2 1 3 3 2 1 4 3 2 4 1 2 1 4 3 2 4 3 1 2 4 1 3 3 1 4 2 1 3 2 4 1 4 3 2 一共有11种。 |
当推为n 时的结果时 我们可以考虑:
为n-1是的情况 比如n=4
_1_ 3_ 2_
_2 _1 _3_
_3 _2_ 1_
我们可以把4放到横线处但要除去3前的共有 3*a[3]种情况
这样我们少考虑了两种
2 4 3 1 3 1 4 2 也就是说前123里可以有两个数相连 比如 231 312 但我们可以将4 填到两个数中间,也就是前3个只有一对数相连,23 或者13 的情况数 ,把4拆它们,可以选2和1 ,或者 3,2 剩下的数 都不相连 ,把4拆它们, 这样就没有相连的了
#include<bits/stdc++.h>
#include<string>
#include <iostream>
using namespace std;
long long a[1000001];
const long long mod = 1000000007;
int main()
{
a[0]=1;
a[1] =1 ;
for(long long i =2;i<=1000000;i++)
{
a[i]= (i-1)*a[i-2]+i*a[i-1];
a[i]%=mod;
// cout<<a[i]<<endl;
}
int T;
scanf("%d",&T);
while(T--){
long long n ;
scanf("%lld",&n);
printf("%lld\n",a[n-1]);
}
return 0;
}