NC15034 德玛西亚万岁(状压dp)

题目链接

题意:
有 n ∗ m 的 01 矩 阵 有n*m的01矩阵 nm01
1 表 示 可 以 放 置 一 个 英 雄 , 0 表 示 不 能 1表示可以放置一个英雄,0表示不能 10
任 意 两 个 英 雄 不 能 相 邻 放 置 任意两个英雄不能相邻放置
问 总 共 有 多 少 种 方 案 数 , m o d   1 e 8 问总共有多少种方案数,mod~1e8 ,mod 1e8
题解:
n , m < = 12 n,m<=12 n,m<=12
这 么 小 的 数 据 最 先 想 到 的 就 是 暴 力 这么小的数据最先想到的就是暴力
D F S 进 行 状 态 搜 索 并 且 记 录 合 法 状 态 DFS进行状态搜索并且记录合法状态 DFS
但 是 方 案 数 情 况 很 多 , 所 以 可 能 会 超 时 但是方案数情况很多,所以可能会超时

对 于 每 个 位 置 只 有 放 英 雄 和 不 放 英 雄 两 种 状 态 对于每个位置只有放英雄和不放英雄两种状态
所 以 可 以 直 接 考 虑 二 进 制 枚 举 所以可以直接考虑二进制枚举
由 于 上 一 行 可 以 决 定 下 一 行 的 方 案 数 由于上一行可以决定下一行的方案数
所 以 能 够 最 终 确 定 , 是 状 压 D P 所以能够最终确定,是状压DP DP

状 压 d p 枚 举 当 前 行 状 态 和 上 一 行 状 态 进 行 转 移 状压dp枚举当前行状态和上一行状态进行转移 dp
但 是 有 几 种 非 法 状 态 需 要 排 除 但是有几种非法状态需要排除
1. 当 前 二 进 制 位 有 相 邻 1 , 不 符 合 英 雄 不 能 相 邻 1.当前二进制位有相邻1,不符合英雄不能相邻 1.1
直 接 用 这 个 状 态 右 移 和 自 身 相 与 , 如 果 不 为 0 说 明 有 相 邻 直接用这个状态右移和自身相与,如果不为0说明有相邻 0
2. 当 前 二 进 制 位 为 1 的 地 方 在 01 矩 阵 中 为 0 , 不 能 放 置 英 雄 2.当前二进制位为1的地方在01矩阵中为0,不能放置英雄 2.1010
直 接 暴 力 查 看 有 没 有 二 进 制 位 1 的 地 方 01 矩 阵 为 0 的 去 除 情 况 直接暴力查看有没有二进制位1的地方01矩阵为0的去除情况 1010
3. 当 前 行 和 上 一 行 枚 举 的 二 进 制 位 有 相 邻 3.当前行和上一行枚举的二进制位有相邻 3.
如 果 当 前 行 枚 举 的 二 进 制 位 和 上 一 行 枚 举 的 相 与 不 为 0 说 明 有 相 邻 如果当前行枚举的二进制位和上一行枚举的相与不为0说明有相邻 0

去 除 掉 这 三 种 情 况 后 , 把 转 移 到 第 n 行 的 所 有 情 况 加 起 来 就 是 结 果 去除掉这三种情况后,把转移到第n行的所有情况加起来就是结果 n
AC代码

/*
    Author:zzugzx
    Lang:C++
    Blog:blog.csdn.net/qq_43756519
*/
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define SZ(x) (int)x.size()
#define endl '\n'
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const int mod=1e9+7;
//const int mod=998244353;
const double eps = 1e-10;
const double pi=acos(-1.0);
const int maxn=1e5+10;
const ll inf=0x3f3f3f3f;
const int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}};

const int p=1e8;
int n,m;
ll g[20][20],dp[20][5000];
bool ok(int st,int i){
    for(int j=0;j<m;j++)
        if((st>>j)&1&&!g[i][j])return 0;
    return 1;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    while(cin>>n>>m){
        memset(dp,0,sizeof dp);
        for(int i=1;i<=n;i++)
            for(int j=0;j<m;j++)
                cin>>g[i][j];
        dp[0][0]=1;
        for(int i=1;i<=n;i++){
            for(int st=0;st<(1<<m);st++){
                if(st&(st>>1)||!ok(st,i))continue;
                for(int st1=0;st1<(1<<m);st1++){
                    if(st1&st)continue;
                    dp[i][st]=(dp[i][st]+dp[i-1][st1])%p;
                }
            }
        }
        ll ans=0;
        for(int i=0;i<(1<<m);i++)ans=(ans+dp[n][i])%p;
        cout<<ans<<endl;
    }
    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
图像识别技术在病虫害检测中的应用是一个快速发展的领域,它结合了计算机视觉和机器学习算法来自动识别和分类植物上的病虫害。以下是这一技术的一些关键步骤和组成部分: 1. **数据收集**:首先需要收集大量的植物图像数据,这些数据包括健康植物的图像以及受不同病虫害影响的植物图像。 2. **图像预处理**:对收集到的图像进行处理,以提高后续分析的准确性。这可能包括调整亮度、对比度、去噪、裁剪、缩放等。 3. **特征提取**:从图像中提取有助于识别病虫害的特征。这些特征可能包括颜色、纹理、形状、边缘等。 4. **模型训练**:使用机器学习算法(如支持向量机、随机森林、卷积神经网络等)来训练模型。训练过程中,算法会学习如何根据提取的特征来识别不同的病虫害。 5. **模型验证和测试**:在独立的测试集上验证模型的性能,以确保其准确性和泛化能力。 6. **部署和应用**:将训练好的模型部署到实际的病虫害检测系统中,可以是移动应用、网页服务或集成到智能农业设备中。 7. **实时监测**:在实际应用中,系统可以实时接收植物图像,并快速给出病虫害的检测结果。 8. **持续学习**:随着时间的推移,系统可以不断学习新的病虫害样本,以提高其识别能力。 9. **用户界面**:为了方便用户使用,通常会有一个用户友好的界面,显示检测结果,并提供进一步的指导或建议。 这项技术的优势在于它可以快速、准确地识别出病虫害,甚至在早期阶段就能发现问题,从而及时采取措施。此外,它还可以减少对化学农药的依赖,支持可持续农业发展。随着技术的不断进步,图像识别在病虫害检测中的应用将越来越广泛。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值