泡沫

博客园 首页 联系 订阅 管理

题目链接: http://www.codeforces.com/problemset/problem/285/D

Permutation p is an ordered set of integers p1,  p2,  ...,  pn, consisting of n distinct positive integers, each of them doesn't exceed n. We'll denote the i-th element of permutation p as pi. We'll call number n the size or the length of permutation p1,  p2,  ...,  pn.

Petya decided to introduce the sum operation on the set of permutations of length n. Let's assume that we are given two permutations of length n: a1, a2, ..., an and b1, b2, ..., bn. Petya calls the sum of permutations a and b such permutation c of length n, where ci = ((ai - 1 + bi - 1) mod n) + 1 (1 ≤ i ≤ n).

Operation means taking the remainder after dividing number x by number y.

Obviously, not for all permutations a and b exists permutation c that is sum of a and b. That's why Petya got sad and asked you to do the following: given n, count the number of such pairs of permutations a and b of length n, that exists permutation c that is sum of a and b. The pair of permutations x, y (x ≠ y) and the pair of permutations y, x are considered distinct pairs.

As the answer can be rather large, print the remainder after dividing it by 1000000007 (109 + 7).

Input

The single line contains integer n (1 ≤ n ≤ 16).

Output

In the single line print a single non-negative integer — the number of such pairs of permutations a and b, that exists permutation c that is sum of a and b, modulo 1000000007 (109 + 7).

Sample test(s)
Input
3
Output
18
Input
5
Output
1800

题目意思是: 求3个序列满足c[i] = (a[i]+b[i]-2)%n的个数, 每个序列都是n个不同的数字。 其实就是c[i] = (a[i]+b[i])%n(范围是0---n-1)
数据<=16,状态压缩的标志啊。
解法是对于一个给定的a序列,求满足条件的bc序列个数。用状态压缩求解。
依次检查b序列那些位没有用,而且c的(the position of a + the position of b)%n也没有用。则可以继续往下搜索。
求出的是a一个序列的解。而a有n!个序列,是不是每个都要求一次呢? 很明显不是的。a的每个序列都是等价的,所以最终结果为:
ans*n!%mod. 其实这个算法还是很慢的,因为我跑n=15的时候跑了蛮久的。 预处理出来打表是可以的。

my python code:这个是状态压缩代码
 1 ans = 0
 2 mod = 1000000007
 3 f = [1]*17
 4 for i in xrange(1, 17):
 5     f[i] = (i*f[i-1])%mod
 6 def dfs(Id, bNum, cSum, n):
 7     global ans
 8     if Id == n:
 9         ans += 1
10         if ans >= mod : ans -= mod
11         return 0    
12     for i in xrange(n):
13         if bNum&(1<<i): continue
14         if cSum&(1<<( (Id+i)%n ) ): continue
15         dfs(Id+1, bNum|(1<<i), cSum|(1<<( (Id+i)%n ) ), n )
16 
17 if __name__ == '__main__':
18     n = input()
19     dfs(0, 0, 0, n)
20     print ans*f[n]%mod

有了上面的代码就可以打表了:

num = [1, 18, 1800,670320,734832000,890786230,695720788,150347555]
n = input()
print 0 if not n&1 else num[n>>1]

 



posted on 2013-05-18 16:05  木-天空  阅读(692)  评论(0编辑  收藏  举报