zoukankan      html  css  js  c++  java
  • Codeforces Round #175 (Div. 2)

    D题, 纠结, 一开始想用组合数学的方法可是想不出怎么排列组合, 然后又准备暴力结果发现普通暴力在n=15的时候就不知道要运行多少时间。。。

    于是去学习了一个 中途相遇的 搜索算法,快了很多, n=15的那组数据也可以在20s内跑完.

    其实这个算法就是将 n^n 的复杂度变成了 2*n^(n/2) ,  可以快很多....

    本质就是将整个搜索过程分成两半来搜。

    D. Permutation Sum
    time limit per test
    3 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    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


    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    using namespace std;
    #define MOD 1000000007
    typedef __int64 LL;
    
    int n;
    int n1,n2;
    int g1[20],g2[20];
    int key;
    int cnt1,cnt2;
    LL sum1[1<<17],sum2[1<<17];
    
    int pan(int i,int k)
    {
        int sum=0;
        while(i)
        {
            sum += i&1;
            i=i>>1;;
        }
        return sum==k;
    }
    
    void dfs1(int s)
    {
        if(s>n1)
        {
            sum1[key]++;
            return ;
        }
        for(int i=0;i<cnt1;i++)
        {
            int tmp=g1[i];
            if(g1[i]==-1) continue;
            int tmp1=(tmp+s-2)%n+1;
            if(key & ( 1<<(tmp1-1) ) ) continue;
            key |= ( 1<<(tmp1-1) );
            g1[i]=-1;
            dfs1(s+1);
            g1[i]=tmp;
            key ^= ( 1<<(tmp1-1) );
        }
    }
    void dfs2(int s)
    {
        if(s>n)
        {
            sum2[key]++;
            return ;
        }
        for(int i=0;i<cnt2;i++)
        {
            int tmp=g2[i];
            if(g2[i]==-1) continue;
            int tmp1=(tmp+s-2)%n+1;
            if(key & ( 1<<(tmp1-1) ) ) continue;
            key |= ( 1<<(tmp1-1) );
            g2[i]=-1;
            dfs2(s+1);
            g2[i]=tmp;
            key ^= ( 1<<(tmp1-1) );
        }
    }
    
    int main()
    {
        for(int i=1;i<=16;i++)
        {
            n=i;
            n1=n/2; n2=n-n1;
            LL ans=0;
            for(int i=0;i<=(1<<n)-1;i++)
            {
                if(pan(i,n1)==0) continue;
                cnt1=0; cnt2=0;
                for(int j=0;j<n;j++)
                {
                    if( (1<<j)&i ) g1[cnt1++]=j+1;
                    else g2[cnt2++]=j+1;
                }
                memset(sum1,0,sizeof(sum1));
                memset(sum2,0,sizeof(sum2));
                key=0; // 主要用来记录c的情况...
                dfs1(1);
                key=0;
                dfs2(n1+1);
                for(int j=0;j<=(1<<n)-1;j++)
                {
                    int tmp=j^((1<<n)-1);
                    ans=(ans+(sum1[j]*sum2[tmp])%MOD)%MOD;
                }
            }
            for(int i=1;i<=n;i++)
                ans=(ans*i)%MOD;
            printf("%I64d,",ans);
        }
        return 0;
    }
    
    /*#include <stdio.h>
    
    int g[20]={0,1,0,18,0,1800,0,670320,0,734832000,0,890786230,0,695720788,0,150347555,0};
    
    int main()
    {
        int n;
        scanf("%d",&n);
        printf("%d",g[n]);
    }*/
  • 相关阅读:
    js 面试的坑:变量提升
    meta 标签大全
    一个极为简单的requirejs实现
    AMD 的 CommonJS wrapping
    浅解析js中的对象
    javascript运动系列第二篇——变速运动
    开发汉澳即时通信网,2006年上线,QQ死期到了
    SpringMVC中的异步提交表单
    HDU 3698 DP+线段树
    黑马程序猿_反射、内省、泛型
  • 原文地址:https://www.cnblogs.com/chenhuan001/p/3022476.html
Copyright © 2011-2022 走看看