德玛西亚是一个实力雄厚、奉公守法的国家,有着功勋卓著的光荣军史。
这里非常重视正义、荣耀、职责的意识形态,这里的人民为此感到强烈自豪。
有一天他们想去制裁邪恶的比尔吉沃特,于是派遣了自己最优秀的战士。
结果比尔吉沃特领土太小,只有长为n宽为m共计n*m块土地,其中有些土
地标记为0表示为高山峻岭或者深海湖泊,英雄们无法在其中站立,只有标
记为1的土地才能容纳一个英雄。德玛西亚的英雄们战斗时有一个特点,他
们不希望队友站在自己旁边显得很暧昧。请问最多能有多少种安排德玛西
亚英雄的方法?
输入描述:
输入包含多组测试数据;
每组数据的第一行包含2个整数n和m (n <= 12, m <= 12 ),之间用空格隔开;
接下来的n行,每行m个数,表示n*m的比尔吉沃特领土。
输出描述:
输出一个整数n代表安排应用的方法。
(答案取膜100000000)
示例1
输入
3 3 1 1 1 0 1 1 1 0 0
输出
24
#include<bits/stdc++.h> using namespace std; const int mod=1e8; const int maxn=12; int a[maxn+5][maxn+5],b[maxn+5],cnt[1<<maxn+5],f[1<<maxn+5],dp[maxn+5][maxn*maxn/2+5][1<<maxn],ans; int low_bit(int i) { return i&(-i); } int check(int i) { while(i) { if((i&1)&((i>>1)&1)) return 1; i>>=1; } return 0; } void init() { for(int i=1;i<(1<<maxn);i++) cnt[i]=cnt[i-low_bit(i)]+1; for(int i=3;i<(1<<maxn);i++) f[i]=check(i); } int main() { int n,m,i,j,k,l; init(); while(scanf("%d%d",&n,&m)!=EOF) { memset(b,0,sizeof(b)); memset(dp,0,sizeof(dp)); ans=0; for(i=1;i<=n;i++) { for(j=0;j<m;j++) { scanf("%d",&a[i][j]); b[i]=b[i]*2+a[i][j]; } } dp[0][0][0]=1; for(i=1;i<=n;i++) { for(j=0;j<=72;j++) { for(k=0;k<(1<<m);k++) { if(f[k]) continue; if((k|b[i])!=b[i]) continue; if(j<cnt[k]) continue; for(l=0;l<(1<<m);l++) { if(k&l) continue; dp[i][j][k]=(dp[i][j][k]+dp[i-1][j-cnt[k]][l])%mod; } } } } for(i=0;i<=72;i++) for(j=0;j<(1<<m);j++) ans=(ans+dp[n][i][j])%mod; printf("%d\n",ans); } return 0; }