UVa 11795 状压DP Mega Man's Mission

kill[S]表示消灭机器人的集合为S,剩下的所能杀死的机器人集合。

设d(S)表示杀死机器人集合为S的方法数,答案为d((1<<n) - 1)。

d(S)可以由d(S')转移过来,其中S'为S中少一个机器人的子集,而且S'的状态下能够杀死缺少的这个机器人。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 const int maxn = 16;
 8 const int maxs = (1 << 16);
 9 
10 int n;
11 
12 int kill[maxs + 10], p[maxn + 10];
13 long long d[maxs + 10];
14 
15 char s[maxn + 10];
16 
17 int main()
18 {
19     int T; scanf("%d", &T);
20     for(int kase = 1; kase <= T; kase++)
21     {
22         scanf("%d", &n);
23         for(int i = 0; i <= n; i++)
24         {
25             p[i] = 0;
26             scanf("%s", s);
27             for(int j = 0; j < n; j++) if(s[j] == '1') p[i] |= (1 << j);
28         }
29         int all = (1 << n) - 1;
30         for(int i = 0; i <= all; i++)
31         {
32             kill[i] = p[0];
33             for(int j = 0; j < n; j++) if(i & (1 << j))
34                 kill[i] |= p[j+1];
35         }
36 
37         memset(d, 0, sizeof(d));
38         d[0] = 1;
39         for(int S = 1; S <= all; S++)
40         {
41             for(int i = 0; i < n; i++) if(S & (1 << i))
42             {
43                 int _S = S ^ (1 << i);
44                 if(kill[_S] & (1 << i)) d[S] += d[_S];
45             }
46         }
47         printf("Case %d: %lld\n", kase, d[all]);
48     }
49 
50     return 0;
51 }
代码君

 

posted @ 2015-08-10 08:57  AOQNRMGYXLMV  阅读(226)  评论(0编辑  收藏  举报