• codeforces 285 D Permutation Sum (状态压缩DP) 木


    题目链接: 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]


  • 相关阅读:
    Servlet的生命周期?
    C++图结构的图结构操作示例
    如何从google play下载app应用,直接下载apk
    C# Socket异步聊天例子
    三极管饱和,放大,截止电压判断
    java中的浮点(float)运算
    微软2014校园招聘笔试试题
    软件开发中的资源控制问题学习
    linux mount命令学习
    17、Spring Boot普通类调用bean【从零开始学Spring Boot】
  • 原文地址:https://www.cnblogs.com/TengXunGuanFangBlog/p/codeforcesProlem_DP.html
Copyright © 2020-2023  润新知