算法竞赛入门经典 每日一题(德玛西亚万岁)

本文解析了一个关于德玛西亚英雄如何在比尔吉沃特领土上合理分布,避免相邻站立的问题,运用位运算和动态规划方法求解最多可行的布阵方案。通过实例演示和代码实现,探讨了如何通过状态压缩和合法性判断来计算最优安排数量。
摘要由CSDN通过智能技术生成


 

题目描述

 

德玛西亚是一个实力雄厚、奉公守法的国家,有着功勋卓著的光荣军史。

这里非常重视正义、荣耀、职责的意识形态,这里的人民为此感到强烈自豪。

有一天他们想去制裁邪恶的比尔吉沃特,于是派遣了自己最优秀的战士。

结果比尔吉沃特领土太小,只有长为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;
    }
    
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

郭晋龙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值