606第十周周六赛 C - 吉哥系列故事――礼尚往来



C - 吉哥系列故事――礼尚往来
Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u
Submit  Status  Practice  HDU 4535

Description

  吉哥还是那个吉哥 
  那个江湖人称“叽叽哥”的基哥 
   
  每当节日来临,女友众多的叽叽哥总是能从全国各地的女友那里收到各种礼物。 
  有礼物收到当然值得高兴,但回礼确是件麻烦的事! 
  无论多麻烦,总不好意思收礼而不回礼,那也不是叽叽哥的风格。 
   
  现在,即爱面子又抠门的叽叽哥想出了一个绝妙的好办法:他准备将各个女友送来的礼物合理分配,再回送不同女友,这样就不用再花钱买礼物了! 
   
  假设叽叽哥的n个女友每人送他一个礼物(每个人送的礼物都不相同),现在他需要合理安排,再回送每个女友一份礼物,重点是,回送的礼物不能是这个女友之前送他的那个礼物,不然,叽叽哥可就摊上事了,摊上大事了...... 
   
  现在,叽叽哥想知道总共有多少种满足条件的回送礼物方案呢? 
 

Input

输入数据第一行是个正整数T,表示总共有T组测试数据(T <= 100); 
每组数据包含一个正整数n,表示叽叽哥的女友个数为n( 1 <= n <= 100 )。 
 

Output

请输出可能的方案数,因为方案数可能比较大,请将结果对10^9 + 7 取模后再输出。 
每组输出占一行。 
 

Sample Input

      
      
      
      
3 1 2 4
 

Sample Output

      
      
      
      
0 1 9

典型的错排,错排方法如下:当n个编号元素放在n个编号位置,元素编号与位置编号各不对应的方法数用D(n)表示,那么D(n-1)就表示n-1个编号元素放在n-1个编号位置,各不对应的方法数,其它类推. 
第一步,把第n个元素放在一个位置,比如位置k,一共有n-1种方法; 
第二步,放编号为k的元素,这时有两种情况:⑴把它放到位置n,那么,对于剩下的n-1个元素,由于第k个元素放到了位置n,剩下n-2个元素就有D(n-2)种方法;⑵第k个元素不把它放到位置n,这时,对于这n-1个元素,有D(n-1)种方法; 
综上得到 
D(n) = (n-1) [D(n-2) + D(n-1)] 
特殊地,D(1) = 0, D(2) = 1. 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int main()
{
    int t,i,j,n;
    long long a[110];
    a[1]=0,a[2]=1;;
    for(i=3; i<110; i++)
    {
        a[i]=a[i-1]+a[i-2];
        a[i]%=(1000000007);
        a[i]*=i-1;
        a[i]%=(1000000007);
    }
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        printf("%I64d\n",a[n]);
    }
    return 0;
}


你可能感兴趣的:(606第十周周六赛 C - 吉哥系列故事――礼尚往来)