哈尔滨理工大学第六届程序设计团队赛—H

problem H.Permutation

TimeLimit: 1000ms  Memory Limit: 100000k

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

Output

2

1

4

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种。


【分析】

错排,自己推导一下公式就可以了,或者找规律也可以发现这道题的公式

f(n)=(n-1)*[f(n-1)+f(n-2)]-f(n-2);

关于错排问题,在另一篇文章.


【代码】

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #include <stdio.h>  
  2. #define MOD 1000000007  
  3. long long a[2001000];  
  4. int main()  
  5. {  
  6.     a[1]=1;  
  7.     a[2]=1;  
  8.     for (int i=3;i<=2000000;i++) a[i]=((i-1)*((a[i-1]+a[i-2])%MOD)%MOD-a[i-2])%MOD;  
  9.     int pp;scanf("%d",&pp);  
  10.     while (pp--)  
  11.     {  
  12.         int n;scanf("%d",&n);  
  13.         printf("%lld\n",a[n]);  
  14.     }  
  15.     return 0;  
  16. }  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值