您的位置:首页 > 其它

UVAlive 5971 Permutation Counting

2014-07-23 09:44 399 查看
Permutation Counting

Dexter considers a permutation of first N natural numbers good if it doesn't have x and x+1 appearing cons ecutively, where (1 ≤ x < N). For example, for N=3, all good permutations are:

1.{1, 3, 2}

2.{2, 1, 3}

3.{3, 2, 1}

Input

Input starts with an integer T (≤ 10000), denoting the number of test cases.Each case starts with a line containing an integer N (1 ≤ N ≤ 10^6).

Output

For each case, print the case number and the number of good permutations modulo 1000000007.

Sample Input

3

2

3

5

Sample Output

Case 1: 1

Case 2: 3

Case 3: 53
解析

这道题是一道推公式的数学题 f[i]表示n=i的good permutations

f[i]=f[i-1]*(i-1)+f[i-2]*(i-2)

其中f[i-1]*(i-1)很容易想到对于i-1合法排列插入i(只要i不插在i-1后就可以)这样的空位总共有i-1个

例如对于n=4

_1_3 2_

_2_1_3

_3 2_1_

后面的f[i-2]*(i-2)稍稍难一点,我们可以考虑有一组x x+1相连的情况,只要把 i 插在x x+1之间就合法了。比如考虑n=5 对于2 3 1 4这样一组非法的序列在2 3间插入4就合法了。这时候计算总共有多少个仅有2 3相连的非法序列:

因为仅有2 3相连所以把2 3看做一个整体(我们姑且把这个整体看做2)且要保证这个整体前面不是1后面不是4然后再变换一下:2 3整体看做2 比3大的数减1(这样4就变成了3 就不能排在2后面了 换句话说2 3 4肯定不会连在一起)问题就转化成了求i-2的合法序列数。

2 3 1 4

2 1 3

像x x+1这样的在i-1中能组成i-2对,所以f[i-2]*(i-2)

这样就推出f[i]=f[i-1]*(i-1)+f[i-2]*(i-2)

#include<cstdio>
using namespace std;
long long dp[1000005];

int main()
{
dp[1]=1;
dp[2]=1;
for(int i=3;i<=1000000;i++)
dp[i]=(dp[i-1]*(i-1)%1000000007+dp[i-2]*(i-2)%1000000007)%1000000007;

int T;
scanf("%d",&T);
for(int i=1;i<=T;i++)
{
int a;
scanf("%d",&a);
printf("Case %d: %lld\n",i,dp[a]);
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: