暑假集训Day2 状压dp 特殊方格棋盘
首先声明 : 这是个很easy的题 可这和我会做有什么关系
题目大意:
在n*n的方格棋盘上放置n个车,某些格子不能放,求使它们不能互相攻击的方案总数。
注意:同一行或同一列只能有一个车,否则会相互攻击、
输入:
输入文件第一行,有两个数n, m ,n表示方格棋盘大小,m表示不能放的格子数量
下面有m行,每行两个整数,为不能放的格子的位置。
算法分析:
1. 显然这是个状压dp(好吧没有那么显然,但是是状压dp就完了) 状态很多而且给出的数据范围很小(这个题给出的20>=n)
2. 我们定义一个数组f[i],表示第 i 个状态所满足的方案数
举个栗子: 1011 就可以表示当前行的状态为第二列还可以放车,而第一三四行已经在之前的状态中放车了(~~一列只能有一个车这不是显然吗~~)
3. 题中给出一个限制 , 即有m个位置是不能放车的 , 我们用a数组存储该位置
**这个地方就要按着状压dp自己的方式存储了**
再举个栗子: 如果第二行第三列有个障碍物 那么我们将a[2] += 1<<(3-1)(这里将a数组初始化为0 想象一下一个二进制串在是0的时候 就是 000000 如果要在第三列的位置加上障碍物 可以想象到就是000100 也就是0 + 1<<(3-1))
4. 在这个地方我们先提及一下lowbit数组 `int lowbit(int x){return x & -x;}`
lowbit数组的目的是求出x的二进制表示中最小位的1的位置
还是举个例子 101000 lowbit的结果就是1000
1100 lowbit的结果就是100
具体实现可参见度娘
lowbit数组具体用处我们已经了解了 那么lowbit数组有什么用呢?
再来回想一下我们定义的f数组 当前i表示状态 如果我们用 for(int i=S;i;i-=lowbit(i))cnt++;这样的代码
很轻松就可以求出当前状态中1的个数 , 也就是当前状态已经放了的车的个数,以及当前为第几行 ,显然个数 = cnt = 第几行(一个n*n的方格,放n个车,每一行有且仅有一个车)
5.然后就可以进行动态转移方程了,具体方程如下
这里的i即枚举的当前行的每一个可能放的车(我们只知道当前行一定会放一个车,但是车在哪里我们并不清楚,因此枚举一遍并累加满足条件的方案书)
而a[cnt]则表示当前行的障碍物情况
刚才我们已经提过lowbit(i)可以求出最右边的i的位置 我们外层的i每次减去一个i 即进行当前行下个车可能位置的求解
注意一个小细节`a[cnt] & lowbit(i)`这里表示当前行障碍物并不与当前行的车位置冲突,可以在这里放车,即可以由上一行的状态转移过来
s = S^lowbit(i) :S 异或 lowbit(i)即求出如果当前行车的位置在lowbit(i)那么上一行的状态就是s 然后累加到当前行的方案数即可
for(int i=S;i;i-=lowbit(i)){
if(!(a[cnt] & lowbit(i))){
int s=S^lowbit(i);
f[S]+=f[s];
}
}
AC代码
#include<bits/stdc++.h>
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 s=S^lowbit(i);
f[S]+=f[s];
}
}
}
printf("%lld\n",f[maxs-1]);
return 0;
}
暑假集训Day2 状压dp 特殊方格棋盘的更多相关文章
- poj 3254 Corn Fields (状压dp)(棋盘dp)
状压dp入门题 因为当前行的状态只和上一行有关 所以可以一行一行来做 因为m <= 12所以可以用二进制来表示放了或者没有放 0表示没放,1表示放 f[i][state]表示第i行状态为stat ...
- [状压dp]HDOJ1565 方格取数(1)
中文题~~ 题意略 $n\le 20$ ! 很明显是状压! #include <cstdio> #include <cstdlib> #include <cstring& ...
- POJ 1185 炮兵阵地 (状压dp)(棋盘dp)
这题和poj 3254很像,但是更复杂了一些 都属于棋盘里放东西,然后又各种各样的限制,然后求方案或者最大值 (1)上一道题距离要大于1,这道题是大于2.所以判断的时候变成 !(x & (x ...
- 暑假集训Day2 互不侵犯(状压dp)
这又是个状压dp (大型自闭现场) 题目大意: 在N*N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. ...
- 暑假集训 || 状压DP
emm 位操作实现技巧: 获得第i位的数据: if(!(data & (1<< i))) 则data的第 i 位为0,else 为 1 设置第i位为1,data=(data | ...
- 暑假集训Day 4 P4163 [SCOI2007]排列 (状压dp)
状压dp (看到s的长度不超过10就很容易想到是状压dp了 但是这个题的状态转移方程比较特殊) 题目大意 给一个数字串 s 和正整数 d, 统计 s 有多少种不同的排列能被 d 整除(可以有前导 0) ...
- HDU 1565&1569 方格取数系列(状压DP或者最大流)
方格取数(2) Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- HDU 1565 - 方格取数(1) - [状压DP][网络流 - 最大点权独立集和最小点权覆盖集]
题目链接:https://cn.vjudge.net/problem/HDU-1565 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32 ...
- 特殊方格棋盘【状压DP】
特殊方格棋盘[状压DP] 讲真状压DP这个东西只不过是有那么亿丢丢考验心态罢了(确信) 先从板子题说起,另加一些基础知识 题目描述 在的方格棋盘上放置n 个车,某些格子不能放,求使它们不能互相攻击的方 ...
随机推荐
- [源创] STM32F103ZET6 基于XMODEM 通讯的 BOOTLOADER案列IAP
网上好多初学者 都想知道如何更好的用IAP,BOOTLOADER 功能 我给大家一个我自己的基于Xmodem的例子, 开发环境 KEIL 5.14 + STD标准库 芯片 STM32F103ZET6 ...
- Alpha总结展望——前事不忘后事之师
这个作业属于哪个课程 软件工程 这个作业要求在哪里 Alpha总结展望--前事不忘后事之师 这个作业的目标 Alpha总结展望 作业正文 正文 其他参考文献 无 一.个人感想总结 吴秋悦: 对Alph ...
- jchdl - RTL实例 - MOS6502 ALU
https://mp.weixin.qq.com/s/nMxYVC2djk7DdAforerZPA 使用jchdl RTL实现MOS6502 CPU的ALU. 参考链接 https://git ...
- 【Linux】文件权限,ssh免密登录
1.文件/文件夹权限 例子: -rw-r--r--. 1 root root 12288 Aug 21 09:50 aliases.db drwxr-xr-x. 2 root root 4096 Au ...
- js匿名函数和date对象,math对象
匿名函数: <script type="text/javascript"> function (参数列表){ 要执行的语句块; } </script> 对象 ...
- Java实现 蓝桥杯VIP 算法训练 方格取数
问题描述 设有NN的方格图(N<=10),我们将其中的某些方格中填入正整数,而其他的方格中则放入数字0. 某人从图的左上角的A 点(1,1)出发,可以向下行走,也可以向右走,直到到达右下角的B点 ...
- Java实现 LeetCode 57 插入区间
57. 插入区间 给出一个无重叠的 ,按照区间起始端点排序的区间列表. 在列表中插入一个新的区间,你需要确保列表中的区间仍然有序且不重叠(如果有必要的话,可以合并区间). 示例 1: 输入: inte ...
- Java实现洛谷 P1428 小鱼比可爱
题目描述 人比人,气死人:鱼比鱼,难死鱼.小鱼最近参加了一个"比可爱"比赛,比的是每只鱼的可爱程度.参赛的鱼被从左到右排成一排,头都朝向左边,然后每只鱼会得到一个整数数值,表示这只 ...
- Java实现判断单联通(强连通缩点+拓扑排序)Going from u to v or from v to u
Description In order to make their sons brave, Jiajia and Wind take them to a big cave. The cave has ...
- js-ajax方法详解以及封装
本文主要从使用ajax请求的步骤.ajax状态码和http响应状态码以及ajax封装三个方面阐述 一.使用ajax请求的步骤 // 一.创建 XMLHttpRequest 对象 var xhr = n ...