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 }

原文地址:https://www.cnblogs.com/ibilllee/p/9313924.html

时间: 2024-08-01 01:41:42

Arrange the Bulls [POJ2441] [状压DP]的相关文章

poj 2441 Arrange the Bulls(状压DP入门)

Arrange the Bulls Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 3509   Accepted: 1344 Description Farmer Johnson's Bulls love playing basketball very much. But none of them would like to play basketball with the other bulls because the

POJ2441 Arrange the Bulls(状压DP)

题目是,有n头牛,每头牛都喜爱某几个草地,要把这n头牛分配给m个不同的它们喜爱的草地,问有几种分配方式. dp[n][S]表示前n头牛分配完毕后占用的草地集合是S的方案数 dp[0][0]=1 dp[n][S]+=dp[n-1][S-x](x∈S且n喜爱x) 不过的状态这样空间开销太大了,事实上n这个维度的信息S就包含了,所以dp[S]即可. 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 u

POJ 2441 Arrange the Bulls(状压DP)

[题目链接] http://poj.org/problem?id=2441 [题目大意] 每个人有过个喜欢的篮球场地,但是一个场地只能给一个人, 问所有人都有自己喜欢的场地的方案数. [题解] 状态S表示已经用了那些场地,顺序递推每个人满足需求的情况即可. [代码] #include <cstdio> #include <cstring> using namespace std; const int N=25; int n,m,u,x,dp[2][1<<20],a[N]

poj 2441 Arrange the Bulls 状压dp入门

题意: 将n头牛和m个栏做匹配,求匹配方案数. 分析: 开始暴搜tle了,还是要用状压dp,dp[i][s]表示前i头牛匹配栏的状态为s时可行的方案数. 代码: //poj 2441 //sep9 #include <iostream> using namespace std; const int maxN=21; int dp[2][1<<maxN]; int a[maxN][maxN]; int main() { int n,m; scanf("%d%d",

状压DP [HDU 1074] Doing Homework

Doing Homework Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 5472    Accepted Submission(s): 2311 Problem Description Ignatius has just come back school from the 30th ACM/ICPC. Now he has a lo

HDU 1074:Doing Homework(状压DP)

http://acm.hdu.edu.cn/showproblem.php?pid=1074 Doing Homework Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 7704    Accepted Submission(s): 3484 Problem Description Ignatius has just come bac

HDU 1074 Doing Homework(状压DP)

Problem Description Ignatius has just come back school from the 30th ACM/ICPC. Now he has a lot of homework to do. Every teacher gives him a deadline of handing in the homework. If Ignatius hands in the homework after the deadline, the teacher will r

【状压DP】【HDOJ1074】

http://acm.hdu.edu.cn/showproblem.php?pid=1074 Doing Homework Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 12269    Accepted Submission(s): 5911 Problem Description Ignatius has just come bac

HDU1074:Doing Homework(状压DP)

Doing Homework Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 15868    Accepted Submission(s): 7718 Problem Description Ignatius has just come back school from the 30th ACM/ICPC. Now he has a l