HDU4949 Light (轮廓线dp)

题意:给你一个01矩阵,有两种操作:

第一种: 把a(i,j)的周围四个都异或一下

第二种: 把a(i, j)的周围四个和a(i,j)都异或一下

求把矩阵变成全0矩阵的最少操作次数

思路:如下图所示的轮廓线dp,逐格递推的,cur为当前决策的格子,红色线就是轮廓线,轮廓线以上的格子的操作状态都已经确定了,而对下面状态有影响的只有黄色格子,每个格子保存的是格子当前的数和它自己操作了多少次,因为无论是1还是2操作,对其他格子的影响都是一样的,这样子的复杂度是O(n*m*4^10),明显是会超时的。然后就是要想办法降低复杂度了,up这个格子如果当前状态是1,那么它还需要cur这个格子操作奇数次使得它达到0状态,也就是说cur格子必须要操作一次,那么up格子自己的操作次数实际上已经没用了,因为不管cur各种操作一次可以异或自己也可以不异或自己,所以cur这个格子可以是0也可以是1。那么就是说只有每个格子只有三种状态了,分别是格子是1,格子是0并且自己操作0次,格子是0并且自己操作了1次。需要注意的是left还是需要保存四个状态的,因为cur会影响left的状态。复杂度为O(n*m*4*
3^9)

code:

HDU4949 Light (轮廓线dp)

时间: 2024-12-18 19:57:13

HDU4949 Light (轮廓线dp)的相关文章

POJ 3254 Corn Fields (状压DP,轮廓线DP)

题意: 有一个n*m的矩阵(0<n,m<=12),有部分的格子可种草,有部分不可种,问有多少种不同的种草方案(完全不种也可以算1种,对答案取模后输出)? 思路: 明显的状压DP啦,只是怎样压缩状态?跟轮廓线DP一样,按格子为单位来设计状态,一个状态只需要表示到其上方和左方的格子,所以最多只需要保存min(n,m)个01状态就行了(可以尝试旋转一下矩阵),最多需要12位.用哈希表来做会比较快吧,不用去考虑无效的状态,比如出现相邻两个1. 1 //#include <bits/stdc++.

轮廓线DP POJ3254

补了一发轮廓线DP,发现完全没有必要从右往左设置状态,自然一点: 5 6 7 8 9 1 2 3 4 如此设置轮廓线标号,转移的时候直接把当前j位改成0或者1就行了.注意多记录些信息对简化代码是很有帮助的,尤其对于我这种代码经常错的一塌糊涂的人来说.. 呆马: #include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <cmath>

轮廓线dp (插头dp)

轮廓线dp 骨牌覆盖问题 n和m比较小 1 #pragma comment(linker, "/STACK:102400000,102400000") 2 3 #include <cstdio> 4 #include <cstdlib> 5 #include <cstring> 6 #include <cmath> 7 #include <ctime> 8 #include <iostream> 9 #includ

POJ 2411 Mondriaan&#39;s Dream( 轮廓线dp )

最普通的轮廓线dp... 复杂度O(nm2min(n, m)) -------------------------------------------------------------------- #include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef long long ll; #define b(x) (1 << (x)) const in

hdu 5766 Filling 轮廓线dp burnside

Filling 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5766 Description The board is a rectangle of unit cells with N rows and N columns. At first, cells are empty. ?? has infinite blocks with the size of 2*2. ?? can put blocks in the board as long

UVa 11270 铺放骨牌(轮廓线DP)

https://vjudge.net/problem/UVA-11270 题意: 用1×2骨牌覆盖n×m棋牌,有多少种方法? 思路: 这道题目是典型的轮廓线DP题. 所谓轮廓线DP,就是以整行整列为状态进行动态规划时无法进行状态转移,那么此时就可以用到轮廓线,当然,这种方法只能使用在一个窄棋盘上,大了肯定是不行的,要超时! ' 轮廓线DP就是按照从上到下,从左到右的顺序进行状态转移,每个格子用二进制来表示状态,1代表的就是覆盖,0代表未覆盖. 以本题为例,如上图,我们现在要计算 k 格子,那么与

poj 2411 Mondriaan&#39;s Dream (轮廓线DP)

题意:有一个n*m的棋盘,要求用1*2的骨牌来覆盖满它,有多少种方案?(n<12,m<12) 思路: 由于n和m都比较小,可以用轮廓线,就是维护最后边所需要的几个状态,然后进行DP.这里需要维护的状态数就是min(n,m).即大概是一行的大小.每次放的时候,只考虑(1)以当前格子为右方,进行横放:(2)以当前格子为下方进行竖放:(3)还有就是可以不放. 3种都是不一样的,所以前面的一种状态可能可以转为后面的几种状态,只要满足了条件.条件是,横放时,当前格子不能是最左边的:竖放时,当前格子不能是

【轮廓线DP】POJ2411-Mondriaan&#39;s Dream

今天美国的院士过来讲课XD以为会很无聊但是谜之好听,而且英语基本上都听懂了的样子?(´▽`) 逃到图书馆来写解题报告 [题目大意] 给出一个m*n的方格,用2*1的骨牌覆盖有几种情况. [思路] 最基础的轮廓线DP.分为三种情况: (1)向上放,必须要满足上面的格子没有被放,且当前不在首行.→新状态=旧状态删去首位,末尾为1: (2)向左放,必须要满足左边的格子和上面的格子都没有放,且当前不在首列.→新状态=旧状态删去首位,末两位微1: (3)不放,必须满足上面的格子没有放.新状态=旧状态删去首

HDU4276 The Ghost Blows Light 树形DP

做这个题的时候想到了,先来一遍最短路,判断是否可以到达,若可以减去最短路的花费,再在剩下的花费里进行DP求最优解,想到了但是没做到,很多细节没有处理好,结果崩盘了,唉,看题解很多人都是两边dfs,不过这位大牛也是先spfa了一遍,  给我这个弱菜看看 刚好,这篇好好记录下来, 最后参考了大牛的:http://blog.csdn.net/acm_cxlove/article/details/7964739,可以说是一模一样了 #include<iostream> #include<cstd