特殊方格棋盘【状压DP】

讲真状压DP这个东西只不过是有那么亿丢丢考验心态罢了(确信)

先从板子题说起,另加一些基础知识

题目描述

在的方格棋盘上放置n 个车,某些格子不能放,求使它们不能互相攻击的方案总数。

注意:同一行或同一列只能有一个车,否则会相互攻击

输入格式

输入文件第一行,有两个数n, m ,n表示方格棋盘大小,m表示不能放的格子数量

下面有m行,每行两个整数,为不能放的格子的位置。

输出格式

输出文件也只有一行,即得出的方案总数。

样例

样例输入

2 1
1 1

样例输出

1

思路分析

状压的核心:1. 二进制表示状态

2.位运算进行转移等操作

  • 状压DP的核心就在于用二进制数表示一种状态,其实是一种非常暴力的算法,举个例子:

    例如dp[s] [v]中,S可以代表已经访问过的顶点的集合,v可以代表当前所在的顶点为v。S代表的就是一种状态(二进制表示),比如 (11001)2 代表在二进制中{0,3,4}三个顶点已经访问过了,(11001)2 代表的十进制数就是25 ,所以当S为25的时候其实就是代表已经访问过了{0,3,4}三个顶点,那假如一共有5个顶点(标号为01234)的话,所有的顶点都访问完毕应该S为什么呢?是 (11111)2。

  • 关于本题:

    • 这题的约束条件非常非常简单,直接告诉了你哪里不能放,那么我们怎么记录这个所给的约束条件呢?

    • 其实也是用二进制的思想,我们开一个数组a[x],表示第x行的限制,如果第x行的第y列不能放置,那么我们就将其对应的二进制位变为1,这里涉及到了位运算——a[x] += 1<<(y-1);

    • 本题还用到了另一个和二进制紧密相关的东西:

      int lowbit(int x){return x & -x;}
      返回值是最后一个二进制数位为1的位置
  • 转移方程:

    int maxs = 1<<n; //显然这是最大的状态,即每个二进制位都是1
    for(int s = 1;s < maxs;s++){
    int cnt = 0;
    for(int i = s;i;i-=lowbit(i))cnt++;//记录二进制1的个数,即放车车的个数(等于行数)
    for(int i = s;i;i-=lowbit(i)){ //根据不能放在同一列进行转移
    if(!(a[cnt] & lowbit(i))){ //首先要保证该位置可以放
    int ss = s^lowbit(i); //异或恰好使得上一行的状态与本行不发生冲突
    f[s] += f[ss];
    }
    }
    }

    另附一张位运算常用操作:

    上代码

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm> const int maxn = (1<<20)-1;
    typedef long long ll;
    ll f[maxn],a[25]; int lowbit(int x){
    return x & -x;
    } int main(){
    int n,m;scanf("%d%d",&n,&m);
    for(int i = 1;i <= m;i++){
    int x,y;scanf("%d%d",&x,&y);
    a[x] += 1<<(y-1);
    }
    f[0] = 1;
    int maxs = 1<<n;
    for(int s = 1;s < maxs;s++){
    int cnt = 0;
    for(int i = s;i;i-=lowbit(i))cnt++;
    for(int i = s;i;i-=lowbit(i)){
    if(!(a[cnt] & lowbit(i))){
    int ss = s^lowbit(i);
    f[s] += f[ss];
    }
    }
    }
    printf("%lld\n",f[maxs - 1]);
    return 0;
    }

发量成功减1%

特殊方格棋盘【状压DP】的更多相关文章

  1. BZOJ 4000: [TJOI2015]棋盘( 状压dp + 矩阵快速幂 )

    状压dp, 然后转移都是一样的, 矩阵乘法+快速幂就行啦. O(logN*2^(3m)) ------------------------------------------------------- ...

  2. 棋盘 || 状压DP

    题意:有一个n*m的棋盘(n,m≤80,n*m≤80)要在棋盘上放k(k≤20)个棋子,使得任意两个棋子不相邻(每个棋子最多和周围4个棋子相邻).求合法的方案总数. 思路:对于每一行,如果把没有棋子的 ...

  3. [BZOJ4000][TJOI2015]棋盘(状压DP+矩阵快速幂)

    题意极其有毒,注意给的行列都是从0开始的. 状压DP,f[i][S]表示第i行状态为S的方案数,枚举上一行的状态转移.$O(n2^{2m})$ 使用矩阵加速,先构造矩阵a[S1][S2]表示上一行为S ...

  4. 【BZOJ4000】【LOJ2104】【TJOI2015】棋盘 (状压dp + 矩阵快速幂)

    Description ​ 有一个\(~n~\)行\(~m~\)列的棋盘,棋盘上可以放很多棋子,每个棋子的攻击范围有\(~3~\)行\(~p~\)列.用一个\(~3 \times p~\)的矩阵给出了 ...

  5. 暑假集训Day2 状压dp 特殊方格棋盘

    首先声明 : 这是个很easy的题 可这和我会做有什么关系 题目大意: 在n*n的方格棋盘上放置n个车,某些格子不能放,求使它们不能互相攻击的方案总数. 注意:同一行或同一列只能有一个车,否则会相互攻 ...

  6. HDU 1565&1569 方格取数系列(状压DP或者最大流)

    方格取数(2) Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

  7. HDU 1565 - 方格取数(1) - [状压DP][网络流 - 最大点权独立集和最小点权覆盖集]

    题目链接:https://cn.vjudge.net/problem/HDU-1565 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32 ...

  8. HDU 1565 方格取数 状压dp

    题目: 给你一个n*n的格子的棋盘,每个格子里面有一个非负数. 从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数的和最大. Input 包括多 ...

  9. POJ 1321 棋盘问题(DFS & 状压DP)

    用DFS写当然很简单了,8!的复杂度,16MS搞定. 在Discuss里看到有同学用状态压缩DP来写,就学习了一下,果然很精妙呀. 状态转移分两种,当前行不加棋子,和加棋子.dp[i][j]中,i代表 ...

随机推荐

  1. js数据劫持 Object.defineProperty() 作用

    原生js Object.defineProperty() 作用 假设我们有一个obj对象,我们要给他设置一个name属性会这么做 Object.defineProperty()也可以设置对象属性 这个 ...

  2. 数据结构&算法

    20个最常用.最基础数据结构与算法: 10个数据结构:数组.链表.栈.队列.散列表.二叉树.堆.跳表.图.Trie 树. 10个 算法      :递归.排序.二分查找.搜索.哈希.贪心.分治.回溯. ...

  3. js高阶函数filter、map、reduce

    // 高阶函数 filter/map/reduce // filter中的回调函数有一个要求:必须返回一个boolean值, // 当返回true时,函数内部会自动将这次回调的 n 加入到新的数组中 ...

  4. RocketMQ系列(五)广播与延迟消息

    今天要给大家介绍RocketMQ中的两个功能,一个是"广播",这个功能是比较基础的,几乎所有的mq产品都是支持这个功能的:另外一个是"延迟消费",这个应该算是R ...

  5. 小师妹学JVM之:JVM的架构和执行过程

    目录 简介 JVM是一种标准 java程序的执行顺序 JVM的架构 类加载系统 运行时数据区域 执行引擎 总结 简介 JVM也叫Java Virtual Machine,它是java程序运行的基础,负 ...

  6. 自己动手实现深度学习框架-8 RNN文本分类和文本生成模型

    代码仓库: https://github.com/brandonlyg/cute-dl 目标         上阶段cute-dl已经可以构建基础的RNN模型.但对文本相模型的支持不够友好, 这个阶段 ...

  7. TensorFlow从0到1之浅谈感知机与神经网络(18)

    最近十年以来,神经网络一直处于机器学习研究和应用的前沿.深度神经网络(DNN).迁移学习以及计算高效的图形处理器(GPU)的普及使得图像识别.语音识别甚至文本生成领域取得了重大进展. 神经网络受人类大 ...

  8. 这一次搞懂Spring的XML解析原理

    前言 Spring已经是我们Java Web开发必不可少的一个框架,其大大简化了我们的开发,提高了开发者的效率.同时,其源码对于开发者来说也是宝藏,从中我们可以学习到非常优秀的设计思想以及优雅的命名规 ...

  9. linux服务器安装宝塔以及一些坑

    首先在linux 下运行这一步命令yum install -y wget && wget -O install.sh http://download.bt.cn/install/ins ...

  10. rust 生命周期2

    之前定义的结构体,都是不含引用的. 如果想定义含引用的结构体,请定义生命周期注解 #[warn(unused_variables)] struct ImportantExcerpt<'a> ...