zoukankan      html  css  js  c++  java
  • Arrange the Bulls [POJ2441] [状压DP]

    题意

    n头牛,m个房间,每头牛有自己喜欢的房间,问每头牛都住进自己喜欢的房间有多少种分配方法?

    Input

    In the first line of input contains two integers N and M (1 <= N <= 20, 1 <= M <= 20). Then come N lines. The i-th line first contains an integer P (1 <= P <= M) referring to the number of barns cow i likes to play in. Then follow P integers, which give the number of there P barns.

    Output

    Print a single integer in a line, which is the number of solutions.
    Sample Input
    3 4
    2 1 4
    2 1 3
    2 2 4
    
    Sample Output
    4
    Analysis
    首先,这种数据我们很容易想到是状压DP
    我们可以比较轻松的写出状态转移方程
    if(status&(1<<room)==0)
      dp[i][status|(1<<room)]+=dp[i-1][status];
    但是我们发现这样是会MLE的,我们就可以采用滚动数组,或是直接上一维
    一维要注意status从大到小循环,因为是每次小的更新大的,status用完之后要清零。
    Code
     1 #include<set>
     2 #include<map>
     3 #include<queue>
     4 #include<stack>
     5 #include<cmath>
     6 #include<cstdio>
     7 #include<cstring>
     8 #include<iostream>
     9 #include<algorithm>
    10 #define RG register int
    11 #define rep(i,a,b)    for(RG i=a;i<=b;++i)
    12 #define per(i,a,b)    for(RG i=a;i>=b;--i)
    13 #define ll long long
    14 #define inf (1<<29)
    15 using namespace std;
    16 int n,m,ans;
    17 int a[25][25];
    18 int dp[1048600];
    19 inline int read()
    20 {
    21     int x=0,f=1;char c=getchar();
    22     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    23     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    24     return x*f;
    25 }
    26 
    27 
    28 int main()
    29 {
    30     n=read(),m=read();
    31     rep(i,1,n)
    32     {
    33         a[i][0]=read();
    34         rep(j,1,a[i][0])
    35             a[i][j]=read();
    36     }
    37     dp[0]=1;
    38     rep(i,1,n)
    39     {
    40         per(j,(1<<m)-1,0)
    41         {
    42             if(!dp[j]) continue;
    43             rep(k,1,a[i][0])
    44             {
    45                 if(!(j&(1<<(a[i][k]-1))))
    46                 {
    47                     dp[j|(1<<(a[i][k]-1))]+=dp[j];
    48                 }
    49             }
    50             dp[j]=0;
    51         }
    52     }
    53     int ans=0;
    54     per(j,(1<<m)-1,0) ans+=dp[j];
    55     cout<<ans;
    56     return 0;
    57 }
  • 相关阅读:
    hdu 2222 Keywords Search
    Meet and Greet
    hdu 4673
    hdu 4768
    hdu 4747 Mex
    uva 1513 Movie collection
    uva 12299 RMQ with Shifts
    uva 11732 strcmp() Anyone?
    uva 1401
    hdu 1251 统计难题
  • 原文地址:https://www.cnblogs.com/ibilllee/p/9313924.html
Copyright © 2011-2022 走看看