poj 2441

来源:互联网 发布:auxre 如何设计软件 编辑:程序博客网 时间:2024/06/05 20:10
http://poj.org/problem?id=2441

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#include <map>
#include <algorithm>
#include <set>
using namespace std;
#define MM(a) memset(a,0,sizeof(a))
typedef long long ll;
typedef unsigned long long ULL;
const int mod = 1000000007;
const double eps = 1e-10;
const int inf = 0x3f3f3f3f;
const int big=50000;
int max(int a,int b) {return a>b?a:b;};
int min(int a,int b) {return a<b?a:b;};
const int N = 500;
const int M=20000;
int fi[25][25],dp[(1<<20)+5];
//dp[j|(1<<k)]+=dp[j];
int main()
{
int n,m,p,l;
while(~scanf("%d %d",&n,&m))
{
memset(fi,0,sizeof(fi));
memset(dp,0,sizeof(dp));

for(int i=1;i<=n;i++)
{
scanf("%d",&p);
for(int k=1;k<=p;k++)
{
scanf("%d",&l);
fi[i][l]=1;
}
}


dp[0]=1;
for(int i=1;i<=n;i++)
for(int j=(1<<m)-1;j>=0;j--)
{
if(!dp[j]) continue;
for(int k=1;k<=m;k++)
{
if(j&(1<<(k-1)))
continue;
if(!fi[i][k])
continue;
dp[j|(1<<(k-1))]+=dp[j];
}
dp[j]=0;
}

int ans=0;
for(int i=0;i<=(1<<m)-1;i++)
ans+=dp[i];
printf("%d\n",ans);
}
return 0;
}


而分析:重做  关键是dp[j],当其为0时,说明不存在,直接跳过,不为0时说明存在,直接在其上加一个数
然后再将dp[j]置为0(递归到了另一状态,为了后面的计数)
原创粉丝点击