• hdu 3811


    Permutation

    Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 372    Accepted Submission(s): 161


    Problem Description
    In combinatorics a permutation of a set S with N elements is a listing of the elements of S in some order (each element occurring exactly once). There are N! permutations of a set which has N elements. For example, there are six permutations of the set {1,2,3}, namely [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], and [3,2,1]. 
    But Bob think that some permutations are more beautiful than others. Bob write some pairs of integers(Ai, Bi) to distinguish beautiful permutations from ordinary ones. A permutation is considered beautiful if and only if for some i the Ai-th element of it is Bi. We want to know how many permutations of set {1, 2, ...., N} are beautiful.
     
    Input
    The first line contains an integer T indicating the number of test cases.
    There are two integers N and M in the first line of each test case. M lines follow, the i-th line contains two integers Ai and Bi.

    Technical Specification
    1. 1 <= T <= 50
    2. 1 <= N <= 17
    3. 1 <= M <= N*N
    4. 1 <= Ai, Bi <= N
     
    Output
    For each test case, output the case number first. Then output the number of beautiful permutations in a line.
     
    Sample Input
    3 3 2 1 1 2 1 3 2 1 1 2 2 4 3 1 1 1 2 1 3
     
    Sample Output
    Case 1: 4 Case 2: 3 Case 3: 18
     
     
    状态压缩就好 state为某个数取或者不取
     
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<string>
    #include<algorithm>
    #include<cstdlib>
    using namespace std;
    long long mp[20][20],A[20],dp[(1<<17)+5];
    int n,m;
    void AA()
    {
        A[0]=1;
        for(int i=1;i<=18;i++)
            A[i]=i*A[i-1];
    }
    int main()
    {
        int tt,ca=1;
        scanf("%d",&tt);
        AA();
        while(tt--)
        {
            memset(mp,0,sizeof(mp));
            memset(dp,0,sizeof(dp));
            scanf("%d%d",&n,&m);
            for(int i=1;i<=m;i++)
            {
                int a,b;
                scanf("%d%d",&a,&b);
                a--,b--;
                mp[a][b]=1;
            }
            dp[0]=1;
            for(int i=0;i<n;i++)
            {
                for(int j=(1<<n)-1;j>=0;j--)
                {
                    if(dp[j]==0)
                        continue;
                    for(int k=0;k<n;k++)
                    {
                        if((j&(1<<k)))
                            continue;
                        if(mp[i][k])
                            continue;
                        dp[j|(1<<k)]+=dp[j];
                    }
                }
            }
            printf("Case %d: %I64d
    ",ca++,A[n]-dp[(1<<n)-1]);
        }
        return 0;
    }
    

      

  • 相关阅读:
    学习记录18
    学习记录17
    学习记录16
    小白的心酸连网历程
    学习记录15
    学习记录14
    学习记录13
    学习记录12
    学习记录10
    语法糖
  • 原文地址:https://www.cnblogs.com/water-full/p/4488506.html
Copyright © 2020-2023  润新知