NC15034. 德玛西亚万岁
描述
德玛西亚是一个实力雄厚、奉公守法的国家,有着功勋卓著的光荣军史。这里非常重视正义、荣耀、职责的意识形态,这里的人民为此感到强烈自豪。有一天他们想去制裁邪恶的比尔吉沃特,于是派遣了自己最优秀的战士。结果比尔吉沃特领土太小,只有长为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
C++14(g++5.4) 解法, 执行用时: 7ms, 内存消耗: 760K, 提交时间: 2020-06-19 22:38:44
#include<bits/stdc++.h> #define Fox ios::sync_with_stdio(false),cin.tie(0),cout.tie(0); using namespace std; const int N=1e5+10; const int mod=100000000; int n,m,x; int dp[13][(1<<13)],mp[13]; int main(){ Fox; while(cin>>n>>m){ memset(mp,0,sizeof(mp)); memset(dp,0,sizeof(dp)); for(int i=1;i<=n;i++) for(int j=0;j<m;j++){ cin>>x; mp[i]=(mp[i]<<1)+x; } dp[0][0]=1; for(int i=1;i<=n;i++) for(int j=0;j<(1<<m);j++){ if((j&mp[i])!=j)continue; if(j&(j>>1))continue; for(int k=0;k<(1<<m);k++){ if(j&k)continue; dp[i][j]=(dp[i][j]+dp[i-1][k])%mod; } } int ans=0; for(int i=0;i<(1<<m);i++)ans=(ans+dp[n][i])%mod; cout<<ans<<"\n"; } return 0; }
C++11(clang++ 3.9) 解法, 执行用时: 11ms, 内存消耗: 840K, 提交时间: 2020-06-02 15:49:45
#include<bits/stdc++.h> using namespace std; const int mod=1e8; int DP[15][1<<13],V[15]; int main() { int i,j,k,n,m,ans; while(~scanf("%d%d",&n,&m)) { memset(DP,0,sizeof(DP)),memset(V,0,sizeof(V)); for(i=1;i<=n;i++) for(j=0;j<m;j++)scanf("%d",&k),V[i]|=(k<<j); for(DP[0][0]=i=1;i<=n;i++) { for(j=0;j<(1<<m);j++) { if((j&(j>>1))||((V[i]|j)!=V[i]))continue; for(k=0;k<(1<<m);k++) { if(k&j)continue; DP[i][j]=(DP[i][j]+DP[i-1][k])%mod; } } } for(ans=i=0;i<(1<<m);i++)ans=(ans+DP[n][i])%mod; printf("%d\n",ans); } return 0; }
Python3 解法, 执行用时: 147ms, 内存消耗: 2852K, 提交时间: 2021-06-08 22:58:24
MOD = 100000000 while True: try: n, m = map(int, input().split()) a = [list(map(int, input().split())) for _ in range(n)] f = [0] * (1 << m) f[0] = 1 for i in range(n): g, b = [0] * (1 << m), [] for j in range(m): if a[i][j] == 1: b.append(j) for j in range(1 << len(b)): t = 0 for k in range(len(b)): if (j & (1 << k)) != 0: t |= 1 << b[k] if (t & (t >> 1)) != 0: continue for k in range(1 << m): if f[k] != 0 and (k & t) == 0: g[t] = (g[t] + f[k]) % MOD f = g print(sum(f) % MOD) except: break