• 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]);
    }*/
  • 相关阅读:
    【IntelliJ Idea】git commit 显示 Local Changes
    【Nginx】worker_connections设置
    【Java Web开发学习】DataSource获取的Connection要不要关闭
    【Redis】LOADING Redis is loading the dataset in memory
    shell 常用
    insert DB
    mq部署
    systemctl启动方式
    mq启动报错ERROR: Please set the JAVA_HOME variable in your environment, We need java(x64)! !!
    redis哨兵centos7开机自启动
  • 原文地址:https://www.cnblogs.com/chenhuan001/p/3022476.html
Copyright © 2020-2023  润新知