HDU5117 - Fluorescent 【状压DP】

化简 Ex3 。X = x1+x2+x3……xn
X3 = ∑xixjxk
即求i,j,k全亮的个数
三层循环I,j,k 对每一个i,j,k 进行DP
t代表第几个开关,x代表状态,x从0到7枚举。
s是状态改变 
按:DP[t+1][x^s]+=DP[t][x]
不按:DP[t+1][x]+=DP[t][x]
ans+=DP[m][7]

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 using namespace std;
 5 #define prt(k) cout<<#k" = "<<k<<endl;
 6 typedef long long ll;
 7 #include <algorithm>
 8 
 9 const ll mod = 1e9 + 7;
10 const int N = 52;
11 ll S[N];
12 int DP[N][8];
13 int n,m ;
14 int i, j, k;
15 int g( ll s)
16 {
17     int ret = 0;
18     if (s >> i & 1) ret ^= 1;
19     if (s >> j & 1) ret ^= 2;
20     if (s >> k & 1) ret ^= 4;
21     return ret;
22 }
23 void add(int &a, int b) { a=(a+b)%mod; }
24 int main()
25 {
26     int re; int ca=1;
27     cin>>re;
28     while (re--)
29     {
30         cin>>n>>m;
31         for (int i=0;i<m;i++)
32         {
33             ll t = 0;
34             int k; cin>>k;
35             while (k--)
36             {
37                 int x ;scanf("%d", &x);
38                 x--;
39                 t |= (1ll<<x);
40             }
41             S[i] = t;
42         }
43         int ans = 0;
44         for (i=0;i<n;i++)
45         {
46             for (j=0;j<n;j++)
47             {
48                 for (k=0;k<n;k++)
49                 {
50                     memset(DP, 0, sizeof DP);
51                     DP[0][0] = 1;
52                     for (int t=0;t<m;t++)
53                     {
54                         int s = g(S[t]);
55                         for (int x=0;x<8;x++)
56                         {
57                             add(DP[t+1][x^s], DP[t][x]);
58                             add(DP[t+1][x], DP[t][x]);
59                         }
60                     }
61                     add(ans, DP[m][7]);
62                 }
63             }
64         }
65         printf("Case #%d: %d\n", ca++, ans);
66     }
67     return 0;
68 }
View Code

 

posted @ 2017-03-18 23:14  HITLJR  阅读(151)  评论(0编辑  收藏  举报