题意: 有n个灯,m个开关,每个开关控制着一些灯。求E(x^3)*(2^m) mod(1e9+7)的值。其中,x为亮着灯的数目。
数据范围: n,m<=50,,
方法:x=(x1+x2+..+xn),,x^3=(x1+x2+..+xn)(x1+x2+..+xn)(x1+x2+..+xn);
展开之后,则对x^3的值有贡献的是xi*xj*xk==1,当且仅当三者为都为1满足要求。
所以可考虑状态压缩,dp[st],,st为当前三灯明灭情况。状态转称时,有
dp[nex_st]+=dp[cur_st];
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
typedef long long ll;
const int Mod=1e9+7;
const int N=55;
int n,m;
bool swi[N][N];
int dp[2][8];
void add(int &x,int y){
x+=y;
if(x>=Mod)x-=Mod;
}
void work(){
int T,tt=1;
scanf("%d",&T);
while(T--){
printf("Case #%d: ",tt++);
scanf("%d%d",&n,&m);
memset(swi,false,sizeof(swi));
for(int i=0;i<m;i++){
int sz;scanf("%d",&sz);
int x;
ll temp=0;
for(int j=0;j<sz;j++){
scanf("%d",&x);x--;
swi[i][x]=true;
}
}
int ans=0;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
for(int k=0;k<n;k++){
int cur,nex;
cur=0;nex=1;
memset(dp[cur],0,sizeof(dp[cur]));dp[cur][0]=1;
for(int t=0;t<m;t++){
memset(dp[nex],0,sizeof(dp[nex]));
int temp=0;
if(swi[t][i])temp|=1;
if(swi[t][j])temp|=2;
if(swi[t][k])temp|=4;
for(int st=0;st<8;st++)if(dp[cur][st]){
add(dp[nex][st],dp[cur][st]);
add(dp[nex][st^temp],dp[cur][st]);
}
cur=!cur;nex=!nex;
}
add(ans,dp[cur][7]);
}
}
}
printf("%d\n",ans);
}
}
int main(){
//freopen("data_in.txt","r",stdin);
work();
return 0;
}