IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 玉米田(状压dp) -> 正文阅读

[C++知识库]玉米田(状压dp)

###题目内容:
农夫约翰的土地由 M×N 个小方格组成,现在他要在土地里种植玉米。

非常遗憾,部分土地是不育的,无法种植。

而且,相邻的土地不能同时种植玉米,也就是说种植玉米的所有方格之间都不会有公共边缘。

现在给定土地的大小,请你求出共有多少种种植方法。

土地上什么都不种也算一种方法。

输入格式
第 1 行包含两个整数 M 和 N。

第 2…M+1 行:每行包含 N 个整数 0 或 1,用来描述整个土地的状况,1 表示该块土地肥沃,0 表示该块土地不育。

输出格式
输出总种植方法对 108 取模后的值。

数据范围
1≤M,N≤12


思路:首先将玉米田反过来存储,便于用按位与运算判断,然后用b[i]存储第i行的玉米田二进制表示,接着dp得到每一行的状态,如果初始化第0行所有状态为1,那么第一行状态就不需要分开写,否则就要分开写,注意每次都要对10^8取余防止爆内存。

(1)其中j&(j<<1)是判断横向是否有玉米相邻种植
(2)j&b[i]是对当前行玉米地判断是否在不育的地方上种上了玉米
(3)还有就是要与f[i-1][t]按位与,确保上下两行不会冲突
就这三个要点判断

AC代码:

using namespace std;
int a[13][13];
int f[13][16384]; 
int b[13];
int n,m;
int t;
int ans;
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        t=0;
        for(int j=1;j<=m;j++)
        {
            cin>>a[i][j];
            a[i][j]=(a[i][j]^1);
            if(a[i][j]==1)
            {
                t+=(1<<(m-j));
            }
         }
         b[i]=t; //存储每行玉米田反二进制表示 
    }
    for(int i=1;i<=n;i++)
    {
        if(i==1)
        {
            for(int j=0;j<(1<<m);j++)
            {
                if((j&b[1])==0&&(j&(j<<1))==0)f[1][j]=1;
            }
        }
        else 
        {
            for(int j=0;j<(1<<m);j++)//上一行状态 
            {
                if(f[i-1][j]!=0)//如果上一行有该状态 
                {
                    for(int k=0;k<(1<<m);k++)
                    {
                      if((k&j)==0&&(k&(k<<1))==0&&(k&b[i])==0)
                      {
                        f[i][k]+=f[i-1][j];
                        f[i][k]%=100000000;
                          } 
                    }
                }
            }
        }
    }
    for(int i=0;i<(1<<m);i++)
    {
        ans+=f[n][i];
        ans%=100000000;
    }
    cout<<ans<<endl;
    return 0;
    /**测试数据 
    4 10
    0 1 1 1 1 1 1 1 1 1
    1 1 1 0 1 1 1 1 1 1
    1 1 1 1 1 1 0 1 1 1
    0 0 1 1 1 1 1 1 1 0
    ans:4402955
    **/
}  
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-02-14 20:56:33  更:2022-02-14 20:57:56 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 7:04:57-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码