【Codeforces 111C】Petya and Spiders
Codeforces 111 C
题意:给\(n\times m\)的网格,每个点上有一个蜘蛛,每个蜘蛛可以向上、下、左、右走一步或者不动,问最多能存在多少没有蜘蛛的点。
思路1:
首先因为\(n\)和\(m\)中小的那个不可能超过\(6\),所以钦定\(m < n\)(因为如果\(n\)和\(m\)互换不影响答案)。
然后就可以考虑状压\(dp\)了。
首先我们看\((x,y)\)这个点上面可爱的小蜘蛛的去向。它可能会往上走,到\((x-1,y)\);也可能向下走,到\((x+1,y)\);也可能向左右走;所以就会发现在不断向下一个点移动的过程中,对于\((x,y)\)有影响的是从\((x-1,y)\)到\((x+1,y)\)的\(2\times m+1\)个点。所以\(dp\)状态和转移方程都可以求出辣:\(dp(x,y,mask)\)表示到了\((x,y)\)这个点,\(mask\)表示从\((x-1,y)\)到\((x+1,y)\)的点是否是蜘蛛集合点。
转移方程和\((x,y)\)上的蜘蛛往哪个方向去走有关,或者它停在原地,它去的那个点必须是蜘蛛集合点,如果原来不是,那么答案必须加1。然后转移到下一个点即可。
思路2:
首先还是钦定\(m < n\)。
然后还是考虑状压\(dp\),其状态为\(dp(x,mask)\)。表示第\(x\)行时的状态。
这里\(mask\)保存的是当前行和上一行的所有的蜘蛛是否已经有地方去,然后转移的时候用\(dfs\)枚举一行中哪些点作为集合点(这里需要枚举所有集合点的集合),同时将其四周的点的状态赋为有地方去,然后让当前行的上一行不要有没地方去的点,继续考虑下一行的\(dp\)。
思路3:
钦定\(m < n\),考虑状压\(dp\),其状态为\(dp(x,mask)\)。
这里\(mask\)保存的是当前行与上一行的集合点集,\(dp\)的值是考虑最多的空闲点的个数。
转移的时候枚举这一行新的集合点集以及下一行的集合点集,然后判断是否有当前行原来是集合点而现在不是的,有没有当前行没地方去的点,如果都没有就可以进入下一行的\(dp\)。
总结:
这3种思路较快的是思路1、2,然后较慢的是思路3,因为思路1的时间复杂度是\(O(n\times m\times 2^{2\times m+1})\),思路2的复杂度是\(O(n\times2^{3\times m})\),思路3的复杂度是\(O(n\times2^{4\times m})\)。
由此可见,状压\(dp\)的状态选择方面,对于复杂度是有非常大的影响的。
2019.03.03补充:
思路:我们考虑状压\(dp\)。\(dp(i,mask0,mask1)\)表示现在我们到了第\(i\)行,第\(i-1\)行的点中\(mask0\)内的的都被十字覆盖过了,第\(i\)行的点中\(mask1\)内的点都被十字覆盖过了,最少的十字数量。
现在枚举以第\(i\)行为中心的十字有哪些,存在\(mask2\)中。然后必须的是第\(i\)行的十字必须将\(mask0\)中可能有的一些空缺填满,然后并且会将\(mask1\)中的\(mask2\)中的点及其左右的点覆盖。这里可以用一种很简单的方式来表示\(mask2\)中的点及其左右:\(mask2|mask2<<1|mask2>>1\)。
然后转移一下就很简单了。
【Codeforces 111C】Petya and Spiders的更多相关文章
- codeforces 111C/112E Petya and Spiders
题目: Petya and Spiders传送门: http://codeforces.com/problemset/problem/111/C http://codeforces.com/probl ...
- 【Codeforces 1042D】Petya and Array
[链接] 我是链接,点我呀:) [题意] 题意 [题解] 把a[i]处理成前缀和 离散化. 枚举i从1..n假设a[i]是区间和的a[r] 显然我们需要找到a[r]-a[l]<t的l的个数 即a ...
- 【codeforces 415D】Mashmokh and ACM(普通dp)
[codeforces 415D]Mashmokh and ACM 题意:美丽数列定义:对于数列中的每一个i都满足:arr[i+1]%arr[i]==0 输入n,k(1<=n,k<=200 ...
- 【codeforces 707E】Garlands
[题目链接]:http://codeforces.com/contest/707/problem/E [题意] 给你一个n*m的方阵; 里面有k个联通块; 这k个联通块,每个连通块里面都是灯; 给你q ...
- 【codeforces 707C】Pythagorean Triples
[题目链接]:http://codeforces.com/contest/707/problem/C [题意] 给你一个数字n; 问你这个数字是不是某个三角形的一条边; 如果是让你输出另外两条边的大小 ...
- 【codeforces 709D】Recover the String
[题目链接]:http://codeforces.com/problemset/problem/709/D [题意] 给你一个序列; 给出01子列和10子列和00子列以及11子列的个数; 然后让你输出 ...
- 【codeforces 709B】Checkpoints
[题目链接]:http://codeforces.com/contest/709/problem/B [题意] 让你从起点开始走过n-1个点(至少n-1个) 问你最少走多远; [题解] 肯定不多走啊; ...
- 【codeforces 709C】Letters Cyclic Shift
[题目链接]:http://codeforces.com/contest/709/problem/C [题意] 让你改变一个字符串的子集(连续的一段); ->这一段的每个字符的字母都变成之前的一 ...
- 【Codeforces 429D】 Tricky Function
[题目链接] http://codeforces.com/problemset/problem/429/D [算法] 令Si = A1 + A2 + ... + Ai(A的前缀和) 则g(i,j) = ...
随机推荐
- matlab 的解函数的不同方式
f=@(x)(sin(x)+2*x); f(pi/2) f=sym('sin(x)+2*x'); subs(f,'x',pi/2) %将 g 表达式中的符号变量 s 用 数值 f 替代 f=i ...
- matlab中常数下的点是什么意思
加上点"."后表示两个矩阵或向量对应位置进行运算, 这时候要求进行操作的两个变量必须维数相同(与矩阵乘法对矩阵维数要求不同)
- MySQL分库分表浅谈
一.分库分表类型 1.单库单表 所有数据都放在一个库,一张表. 2.单库多表 数据在一个库,单表水平切分多张表. 3.多库多表 数据库水平切分,表也水平切分. 二.分库分表查询 通过分库分表规则查找到 ...
- Fundebug前端JavaScript插件更新至1.2.0
摘要: Fundebug的前端JavaScript错误监控插件更新至1.2.0:支持监控WebSocket连接错误:修复了监控unhandledrejection错误的BUG,即未用catch处理的P ...
- H5调拨打电话界面
<a href=”tel:15771791266 ”>拨打电话</a> 切记不要用js调用 直接用a标签 苹果安卓塞班都能调起来
- 使用CSS如何解决inline-block元素的空白间距
早上在博客中有人提了这样一个问题:“li元素inline-block横向排列,出现了未知间隙”,我相信大家在写页面的时候都遇到过这样的情况吧. 我一般遇到这情况都会把li浮动起来,这样就没有间隙.但是 ...
- python 提取linux的硬件信息
1.代码实现目的 注:代码可以直接粘贴使用 为了实现对主机的整体有明确的了解,实现了下面的代码功能 代码主要功能是: 提取到主机的内存.硬盘.CPU.型号等信息 插入到mysql的数据库中 2.代码具 ...
- linux编写.sh脚本并赋权限
今日打包编译项目时,发现缺少一个git pull更新项目的脚本,所以在linux编写了一个gitpull.sh脚本,能够实现更新项目的需求. 1.首先vi gitpull.sh或者使用vim编辑器. ...
- Telephone dialer
运行电话拨号器,需要加这个权限,否则不会打通电话.这个权限是用户权限,是谷歌工程师为了跟自己撇清关系,用户需要权限的时候自己加. 运行android程序的时候提示:ActivityManager: W ...
- recovery 升级界面顶部花屏问题分析
说明: 实际解决问题的过程有点曲折,后面找到原因,分析清楚问题后,总结下正确的分析方法,大致分析流程如下. 问题描述: 在进入recovery的时候,第一次上电进入recovery时,顶部会有一长条花 ...