题意:头牛,
个牛棚,每个牛棚只能有一头牛,每头牛都只能在自己喜欢的牛棚里,给每头牛安排位置,总共有多少种安排方案?
思路:每个牛棚可以放牛也可以不放牛,个牛棚,故可以用状压
,
表示
状态下,给前i头牛分配牛棚的方案数
(
&
,
)
当前状态只与上一状态有关,可以用滚动数组来节省空间
#include <stdio.h>
#include <string.h>
#include <vector>
using namespace std;
int dp[2][1 << 20];
vector<int> like[25];
int main(void)
{
int num,n,m,i,j,k,t,cur,ans;
scanf("%d %d",&n,&m);
for(i = 1; i <= n; i++) {
scanf("%d",&num);
while(num--) {
scanf("%d",&t);
t--;
like[i].push_back(t);
}
}
dp[0][0] = 1;
cur = 0;
for(i = 1; i <= n; i++) {
cur ^= 1;
memset(dp[cur],0,sizeof(dp[cur]));
for(j = 0; j < (1 << m); j++) {
if(dp[cur ^ 1][j] == 0) continue;
for(k = 0; k < like[i].size(); k++) {
t = like[i][k];
if( j & (1 << t) ) continue;
dp[cur][ j | (1 << t) ] += dp[cur ^ 1][j];
}
}
}
ans = 0;
for(i = 0; i < (1 << m); i++)
ans += dp[cur][i];
printf("%d\n",ans);
return 0;
}