链接:https://www.nowcoder.com/acm/contest/74/F
来源:牛客网
德玛西亚是一个实力雄厚、奉公守法的国家,有着功勋卓著的光荣军史。
这里非常重视正义、荣耀、职责的意识形态,这里的人民为此感到强烈自豪。
有一天他们想去制裁邪恶的比尔吉沃特,于是派遣了自己最优秀的战士。
结果比尔吉沃特领土太小,只有长为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
比赛时想到状压dp,但没心情写了,刚才试了试1A了= =今天也算写了一题
0一定是0,1有可能是1也有可能是0,用轮廓线处理就好了,复杂度O(n*m*m*2^m)
一直没写卡在如何使最高位归零真是zz了,1xxxx,&上一个01111就好了。
最后记得注意边界处理。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define LL long long 4 LL mod=100000000; 5 int e[15][15]; 6 LL dp[2][(1<<12)+15]; 7 int main() 8 { 9 int n,m,i,j,k,p; 10 while(cin>>n>>m){ 11 for(i=0;i<n;++i) 12 for(j=0;j<m;++j) cin>>e[i][j]; 13 int cur=0; 14 memset(dp,0,sizeof(dp)); 15 dp[0][0]=1; 16 for(i=0;i<n;++i) 17 { 18 for(j=0;j<m;++j) 19 { 20 cur^=1; 21 memset(dp[cur],0,sizeof(dp[cur])); 22 for(k=0;k<(1<<m);++k) 23 { 24 dp[cur][(k<<1)&((1<<m)-1)]=( 25 dp[cur][(k<<1)&((1<<m)-1)]+dp[cur^1][k]%mod)%mod; 26 if(e[i][j]){ 27 if(j==0){ 28 if(!(k&(1<<(m-1)))) 29 dp[cur][(k<<1)&((1<<m)-1)|1]= 30 (dp[cur][(k<<1)&((1<<m)-1)|1]+dp[cur^1][k])%mod; 31 32 } 33 else{ 34 if(!(k&(1<<(m-1)))) 35 { 36 if(!(k&1)){ 37 dp[cur][(k<<1)&((1<<m)-1)|1]= 38 (dp[cur][(k<<1)&((1<<m)-1)|1]+dp[cur^1][k])%mod; 39 } 40 } 41 } 42 } 43 } 44 } 45 } 46 LL ans=0; 47 for(k=0;k<(1<<m);++k)ans=(ans+dp[cur][k])%mod; 48 cout<<ans<<endl; 49 } 50 return 0; 51 }