POJ 2441 Arrange the Bulls(状态压缩DP)

Arrange the Bulls

Time Limit: 4000MS   Memory Limit: 65536K
Total Submissions: 4234   Accepted: 1612

Description

Farmer Johnson‘s Bulls love playing basketball very much. But none of them would like to play basketball with the other bulls because they believe that
the others are all very weak. Farmer Johnson has N cows (we number the cows from 1 to N) and M barns (we number the barns from 1 to M), which is his bulls‘ basketball fields. However, his bulls are all very captious, they only like to play in some specific
barns, and don’t want to share a barn with the others.

So it is difficult for Farmer Johnson to arrange his bulls, he wants you to help him. Of course, find one solution is easy, but your task is to find how many solutions there are.

You should know that a solution is a situation that every bull can play basketball in a barn he likes and no two bulls share a barn.

To make the problem a little easy, it is assumed that the number of solutions will not exceed 10000000.

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

题意:有n头牛,m个牛圈,需要给每头牛分配一个合适的牛圈。每头牛都想一个人在一个牛圈里,且都有心中指定的牛圈。 现在给出这些牛心中想住进的牛圈。 每行先给出P,后面有P个数字,表示第i头牛想住进的牛圈的编号。 问需要满足以上条件的分配方法有多少种?

题解:状压dp,在递推式过程中我们把每个牛圈有没有住进牛看成一个状态,一共有(1<<m)-1个状态。 dp[i][j]表示第i头牛在第j种状态下有多少种分配方式。 那么状态转移方程为
dp[i][j] = sigma(dp[i-1][k]) k表示牛圈入住的状态,从0到(1<<m)-1  因为dp[20][1<<20]会超内存,这里要用滚动数组。

代码如下:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define maxm 22
int dp[2][1<<20],a[maxm][maxm];
//dp[i][j]表示第i头在第j中状态下的方法数,a[i][j]表示第i头牛能在第j个牛圈里
int main()
{
	int n,m,k,i,j,cnt,num;
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		memset(a,0,sizeof(a));
		for(i=1;i<=n;++i)
		{
			scanf("%d",&cnt);
			while(cnt--)
			{
				scanf("%d",&num);
				a[i][num-1]=1;//为了方便运算把牛圈的编号变为从0~m-1
			}
		}
		memset(dp,0,sizeof(dp));
		dp[0][0]=1;
		for(i=1;i<=n;++i)
		{
			for(j=0;j<(1<<m);++j)
			{
				if(dp[1-(i&1)][j])//表示前一头牛在j状态下有值
				{
					for(k=0;k<m;++k)
					{
						if(a[i][k]&&(j!=(j|(1<<k))))//表示第i头牛能放进k位置且k位置没有其他的牛
							dp[i&1][j|(1<<k)]+=dp[1-(i&1)][j];
					}
				}
			}
			memset(dp[1-(i&1)],0,sizeof(dp[1-(i&1)]));
		}
		int ans=0;
		for(i=1;i<(1<<m);++i)//统计所有结果
			ans+=dp[n&1][i];
		printf("%d\n",ans);
	}
	return 0;
} 
时间: 2024-10-06 09:16:50

POJ 2441 Arrange the Bulls(状态压缩DP)的相关文章

poj 2441 Arrange the Bulls (状态压缩dp+滚动数组)

题意: n头牛和m个barn,每头牛有自己喜欢的p个barn(1<=p<=m),问有多少种安排n头牛的方法. 分析: dp[i][j]表示i头牛在j状态下的方法数. dp[i][j] = sigma(dp[i-1][k])  (k从0到 1<<m). 要用滚动数组优化,否则dp[20][1<<20]会MLE! 注意滚动数组的清空= =! 1 #include<stdio.h> 2 #include<cstring> 3 #include<i

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",

poj 3254 Corn Fields ,状态压缩DP

题目链接 题意: 一个矩阵里有很多格子,每个格子有两种状态,可以放牧和不可以放牧,可以放牧用1表示,否则用0表示,在这块牧场放牛,要求两个相邻的方格不能同时放牛,即牛与牛不能相邻.问有多少种放牛方案(一头牛都不放也是一种方案) state[i] 表示对于一行,保证不相邻的方案 状态:dp[i][ state[j] ]  在状态为state[j]时,到第i行符合条件的可以放牛的方案数 状态转移:dp[i][ state[j] ] =Sigma dp[i-1][state'] (state'为符合条

POJ 1038 Bugs Integrated, Inc. 状态压缩DP

题目来源:1038 Bugs Integrated, Inc. 题意:最多能放多少个2*3的矩形 思路:状态压缩DP啊 初学 看着大牛的代码搞下来的  总算搞懂了 接下来会更轻松吧 3进制代表前2行的状态(i行和i-1行)1代表i-1行占位 2代表i行占位 i-1不管有没有占位都不会影响的0代表i行和i-1行都空闲 然后枚举状态dfs更新状态 话说就不能没写深搜了 有点不会了 #include <cstdio> #include <cstring> #include <alg

[POJ 2411] Mondriaan&#39;s Dream 状态压缩DP

题意 给定一个 n * m 的矩形. 问有多少种多米诺骨牌覆盖. n, m <= 11 . 实现 1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cctype> 5 #define F(i, a, b) for (register int i = (a); i <= (b); i++) 6 #define LL long long 7 inline

poj 3254 Corn Fields(状态压缩dp)

Description Farmer John has purchased a lush new rectangular pasture composed of M by N (1 ≤ M ≤ 12; 1 ≤ N ≤ 12) square parcels. He wants to grow some yummy corn for the cows on a number of squares. Regrettably, some of the squares are infertile and

POJ 2288 Islands And Bridges 状态压缩dp+哈密顿回路

题意:n个点 m条边的图,路径价值定义为相邻点乘积,若路路径c[i-1]c[i]c[i+1]中c[i-1]-c[i+1]有边 则价值加上三点乘积找到价值最大的哈密顿回路,和相应的方法数n<=13.暴力dfs O(13!) TLE 由于n<13 经典的状态压缩dp [状态] [当前点位置 ][前一点位置] 注意上一个状态必须合法才能进行转移设状态dp[s][i][j] 当前状态为s,当前点为i上一个点为j的最大价值, ans=max(dp[(1<<n)-1][i])dp[s][i][

poj 2441 Arrange the Bulls(状态压缩dp)

Description Farmer Johnson's Bulls love playing basketball very much. But none of them would like to play basketball with the other bulls because they believe that the others are all very weak. Farmer Johnson has N cows (we number the cows from 1 to

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