一开始用记忆化搜索写的,最后发现存储状态需要用2^16*2^16的空间,果断放弃。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define ss(x) scanf("%d",&x)
const int maxn=16;
int kill[(1<<maxn)],p[20];
long long f[(1<<maxn)];
int main()
{
int t;
ss(t);
int kase=0;
while(t--)
{
int n;ss(n);
rep(i,0,n){
char cmd[20];
scanf("%s",cmd);
p[i]=0;
rep(j,0,n-1) if(cmd[j]=='1') p[i]|=(1<<j);
}
kill[0]=p[0];
rep(i,1,(1<<n)-1){
kill[i]=p[0];
rep(j,1,n) if(i&(1<<(j-1))) kill[i]|=p[j];
}
memset(f,0,sizeof(f));
f[0]=1;//只杀一个机器人只有一种方法
rep(i,1,(1<<n)-1){
f[i]=0;
rep(j,1,n){
if(kill[i^(1<<(j-1))]&(1<<(j-1))) f[i]+=f[i^(1<<(j-1))];
}
}
printf("Case %d: %lld\n",++kase,f[(1<<n)-1]);
}
return 0;
}