Description
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
Output
Sample Input
3 4 2 1 4 2 1 3 2 2 4
Sample Output
4
这题要处理牛和牛棚两层关系,用状压情况有些复杂;在求方法数的时候先令方法为0,从第一头牛开始遍历找可满足的情况,然后更新后面状态,但是要消除用过的方法,因为如果有两个牛都只能在当前棚显然是满足不了的,只有分开放置,,,背包从大往小遍历;技巧性强
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int N = 20;
int a[N][N], v[N];
int dp[(1<<N)+11];
int main()
{
int n, m;
while(scanf("%d %d", &n, &m)!=EOF)
{
memset(a,0,sizeof(a));
for(int i=0;i<n;i++)
{
int k, x;
scanf("%d", &k);
while(k--)
{
scanf("%d", &x);
x--;
a[i][x]=1;
}
}
memset(dp,0,sizeof(dp));
if(n>m)
{
printf("0\n");
continue;
}
dp[0]=1;
for(int i=0;i<n;i++)
{
for(int j=(1<<m)-1;j>=0;j--)
{
if(dp[j]==0)
continue;
for(int k=0;k<m;k++)
{
if((j&(1<<k))||a[i][k]==0)
continue;
int state=(j|(1<<k));
dp[state]+=dp[j];
}
dp[j]=0;
}
}
int ans=0;
for(int i=0;i<(1<<m);i++)
ans+=dp[i];
printf("%d\n",ans);
}
return 0;
}