题意:洛克人最初只有一个武器,你需要消灭所有的其他机器人,每消灭一个机器人就可以得到他的武器,每一把武器都可以杀死指定的某些机器人
现在你知道每一把武器能杀死的机器人的编号,求出杀死所有机器人的方案数
状压dp,f[s0]表示使状态为s0的方案数,动规时我们要预处理一个os数组,os[s0]表示杀死状态为s0的敌人的时候能够用它们的武器杀死的机器人的状态数,f[s0]+=f[s0^(1<<(i-1))]
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#define LL long long
#define bit(xx) (1<<xx)
using namespace std;
const LL maxn=17;
LL f[bit(maxn)];
LL os[bit(maxn)],cases,w[maxn],t,n;
char ch[maxn],str;
void clear(){
memset(f,0,sizeof(f));
memset(os,0,sizeof(os));
memset(w,0,sizeof(w));
}
int main(){
cin>>t;
LL i,j,s0,s,k;
while(t--){
clear();
scanf("%lld",&n);
for(i=0;i<=n;i++){
scanf("%s",ch);
for(j=0;j<strlen(ch);j++)
if(ch[j]=='1')w[i]|=bit(j);
}
s=bit(n)-1;
for(s0=0;s0<=s;s0++){
os[s0]=w[0];
for(i=1;i<=n;i++)
if(s0&bit(i-1))
os[s0]|=w[i];
}
f[0]=1;
for(s0=1;s0<=s;s0++)
for(i=1;i<=n;i++)
if((s0&bit(i-1))&&(os[s0^bit(i-1)]&bit(i-1)))//i必须包含在s0中且除了s0必须要有其他的状态使i被杀死
f[s0]+=f[s0^bit(i-1)];
printf("Case %lld: %lld\n",++cases,f[s]);
}
}</span>