POJ 2441

题意:n头牛,m个牧场,每头牛都有自己喜欢的牧场,然后问一牛一牧场的分配方案总数。

题解:状态压缩dp,dp[i][state]为前i头牛,用了state的牧场时的总数。但是直接开n*2^m会爆空间,但是每头牛都只与前面一头牛相关,所以可以辗转一下,只记录两维即可。

View Code
 1 #include<cstdio>

 2 #include<cstring>

 3 #include<algorithm>

 4 using namespace std;

 5 int dp[2][(1<<20)+2];

 6 int main()

 7 {

 8     int n,m;

 9     while(scanf("%d%d",&n,&m)!=EOF)

10     {

11         memset(dp,-1,sizeof(dp));

12         int ms=1<<m,a,b;

13         dp[0][0]=1;

14         for(int i=1;i<=n;i++)

15         {

16             b=i&1;a=b^1;

17             memset(dp[b],-1,sizeof(dp[b]));

18             int num;

19             scanf("%d",&num);

20             for(int j=0;j<num;j++)

21             {

22                 int st;

23                 scanf("%d",&st);

24                 st=1<<(st-1);

25                 for(int k=0;k<ms;k++)

26                 {

27                     if(dp[a][k]!=-1&&!(k&st))

28                     {

29                         if(dp[b][k|st]==-1)

30                             dp[b][k|st]=dp[a][k];

31                         else

32                             dp[b][k|st]+=dp[a][k];

33                     }

34                 }

35             }

36         }

37         int ans=0;

38         for(int i=0;i<ms;i++)

39             if(dp[b][i]!=-1)

40                 ans+=dp[b][i];

41         printf("%d\n",ans);

42     }

43     return 0;

44 }

你可能感兴趣的:(poj)