题目意思还是有点绕的,想了好一会
大体上是一个状压dp(废话
f[j] ,当当前拥有武器集合为j 时,消灭所有怪物的方案数
像线性dp一样,但可以去掉一维
f[j]+=f[t] ,t= j^(1<<i ) 条件是 武器库j 能消灭 怪物i
这就要处理出 g[j] ,表示 武器库 j 能消灭的怪物集合
#include<iostream> #include<string> #include <cstring> #include <algorithm> using namespace std; const int N=17; unsigned long long f[1<<N]; int a[N],n,g[1<<N]; main(){ //freopen("in","r",stdin); int i,j,cas,T=0; cin>>cas; while(cas--){ cin>>n; memset(f,0,sizeof f); for(i=0;i<n+1;i++){ char c; a[i]=0; for(j=0;j<n;j++){ cin>>c; if(c=='1') a[i]|=(1<<j); } } g[0]=a[0]; for(i=1;i<(1<<n);i++){ g[i]=a[0]; for(j=0;j<n;j++) if(i&(1<<j)) g[i]|=a[j+1]; } f[0]=1; for(i=0;i<(1<<n);i++) for(j=0;j<n;j++){ int t=i^(1<<j); if(g[t]&(1<<j)) f[i]+=f[t]; } printf("Case %d: %lld\n",++T,f[(1<<n)-1]); } }
标签:cas,long,11795,uva,include,dp From: https://www.cnblogs.com/towboa/p/16836450.html