链接
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2895
题解
集合
S
S
表示它拥有的武器集合,这个集合压缩到一个二进制数中,第位为
1
1
表示拥有这种武器
枚举中的元素
x
x
,用转移
f[S]
f
[
S
]
代码
//״ѹDP
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cctype>
#include <cmath>
#define maxn 17
#define ll long long
#define cl(x,y) memset(x,y,sizeof(x))
using namespace std;
ll N, f[1<<maxn], can[maxn];
void init()
{
cl(f,0);
cl(can,0);
char s[maxn];
ll i, j;
scanf("%d",&N);
for(i=0;i<=N;i++)
{
scanf("%s",s+1);
for(j=1;j<=N;j++)if(s[j]=='1')can[j]|=1<<i;
}
}
void dp()
{
ll i, j;
f[1]=1;
for(i=3;i<(1<<N+1);i+=2)
for(j=1;j<=N;j++)
if(i&(1<<j) and can[j]&(i-(1<<j)))
f[i]+=f[i-(1<<j)];
printf("%lld\n",f[(1<<N+1)-1]);
}
int main()
{
ll T, c;
scanf("%lld",&T);
for(c=1;c<=T;c++)printf("Case %lld: ",c), init(), dp();
return 0;
}