zoukankan      html  css  js  c++  java
  • HaHa's Morning(状压DP)

    描述

    HaHa is so happy today, he is going to participate the 7th Hunan University Programming Contest. He woke up in the morning, and wanted to reach Hunan University as soon as possible, but he realized that he still has N things to do before going on his journey.
    At first, HaHa thought there must have N! (The factorial of N) ways to get everything done, however, he soon found that this was impossible at all, for the work has some annoying restrictions: some things must be done before getting some other things done. Now HaHa is interested in the number of ways to get everything done, and he asks you for help, so your task is to find how many ways are there to finish his work.

    输入

    There are several test cases, each case contains several lines, and the first line of each case is two natural numbers N (that described above) and M ≤ 400 (for the total restrictions for the work).
    The next M lines describes the restrictions, for each line, there is two positive integers A, B, for the A-th thing must be done before the B-th thing.
    The input will finish with the end of file, input is guaranteed that 1 ≤ A, B ≤ N ≤ 17.

    输出

    For each the case, output one number: the ways to finish the work.

    样例输入

    3 2
    1 3
    2 3
    2 2
    1 2
    2 1

    样例输出

    2
    0

    题目大意:

    输入n,m,n代表完成的事的数量,接下来m行,每行输入a,b代表做b之前需要将a做完,求做完所有事的方案种数.

    状压DP,dp[i]代表做完i所表示的二进制对应的事情有的方案数。例:dp[18]对应二进制10010代表做完第二和第五件事的方案数。

    #include <cstdio>
    #include <cstring>
    using namespace std;
    int n,m,pre[20];
    long long dp[1<<17];///17!爆int
    int main()
    {
        while(~scanf("%d%d",&n,&m))
        {
            memset(pre,0,sizeof pre);///pre[i]代表做事情i的前提
            memset(dp,0,sizeof dp);
            for(int i=1,x,y;i<=m;i++)
                scanf("%d%d",&x,&y),pre[y]|=(1<<(x-1));
            dp[0]=1;
            for(int s=0;s<(1<<n);s++)
            {
                if(dp[s]==0) continue;
                for(int i=1;i<=n;i++)
                    if((s&pre[i])==pre[i]&&(s&(1<<(i-1)))==0)///s包含了i的所有前提,但不包括i
                        dp[s|(1<<(i-1))]+=dp[s];///将i加进去
            }
            printf("%I64d
    ",dp[(1<<n)-1]);
        }
        return 0;
    }
  • 相关阅读:
    Web负载均衡的几种实现方式
    Apache和Nginx的区别
    Nginx和Apache区别
    Git 使用中显示“Another git process seems to be running in this repository...”问题解决
    上传本地代码到gitHub过程详解
    MySQL数据库中varchar与char类型的区别
    正则表达式中/i,/g,/ig,/gi,/m的区别和含义
    内行看门道:看似“佛系”的《QQ炫舞手游》,背后的音频技术一点都不简单
    惧怕羊毛党?腾讯云为你保驾护航
    教你1天搭建自己的“微视”
  • 原文地址:https://www.cnblogs.com/zdragon1104/p/9208786.html
Copyright © 2011-2022 走看看