题目描述
德玛西亚是一个实力雄厚、奉公守法的国家,有着功勋卓著的光荣军史。
这里非常重视正义、荣耀、职责的意识形态,这里的人民为此感到强烈自豪。
有一天他们想去制裁邪恶的比尔吉沃特,于是派遣了自己最优秀的战士。
结果比尔吉沃特领土太小,只有长为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
题目描述
德玛西亚是一个实力雄厚、奉公守法的国家,有着功勋卓著的光荣军史。
这里非常重视正义、荣耀、职责的意识形态,这里的人民为此感到强烈自豪。
有一天他们想去制裁邪恶的比尔吉沃特,于是派遣了自己最优秀的战士。
结果比尔吉沃特领土太小,只有长为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 我们结合位运算来判断是否合法
s&(s<<1) 左右是否合法
s&last 判断上下二行相邻位置是否合法
s&a!=s 可以判断是否在0的位置放
const int MAX=10010;
const int mod=1e8;
const int N=15;
int dp[MAX][N<<1];
int s[MAX];
int main(){
int n,m;
while (cin>>n>>m) {
mms(dp,0);
mms(s,0);
for(int i=1;i<=n;i++){
int temp=0;
for(int j=0;j<m;j++){
int x;
cin>>x;
if(x) temp+=(1<<j);
}
s[i]=temp;
}
dp[0][0]=1;
for(int i=1;i<=n;i++){
for(int j=0;j<(1<<m);j++){
if(j&(j<<1)) continue;
if(j&s[i]!=j) continue;
for(int last=0;last<(1<<m);last++){
if(j&last) continue;
dp[i][j]=(dp[i][j]+dp[i-1][last])%mod;
}
}
}
int ans=0;
for(int i=0;i<(1<<m);i++)
ans=(ans+dp[n][i])%mod;
cout<<ans<<endl;
}
}