简单路径的题目,其实就是在状态后面多记了有多少个独立插头. 分类讨论独立插头: 1.只存在上插头或者左插头,可以选择作为独立插头. 2.都不存在上插头和左插头,选择作为独立插头的同时要标号为新的连通块. 换行时需特别注意,因为还有独立插头的判断,如果进行了换行操作,就会乱,特别是在不存在上插头和左插头的情况下. 那要怎么办呢? 我们会发现,换行后,1~m-1往后移,并把code[0]设为0,但我们在encode的时候,code[0] = 0,其实是可以忽略的操作,那么我们只需要做M-1就可以了.…
题解 这题是一道非常好的插头题,与一般的按格转移的题目不同,由于m很大,要矩阵乘法,这题需要你做一个按列转移的插头DP. 按列转移多少与按格转移不同,但大体上还是基于连通性进行转移.每一列只有右插头是对下一列的转移有影响的,那么我们只需要记录每一列的右插头的连通情况,用最小表示法表示为当前列的状态.在转移的时候,我们只知道上一列的右插头,即本列的左插头的情况,而上插头还需要自己记一个标记. 那么我们具体分析: 1.不存在上插头 1.同时存在左插头和右插头,不需要修改当前插头,直接把上一列的右插头…
Beautiful Meadow Time Limit: 2 Seconds      Memory Limit: 65536 KB Tom's Meadow Tom has a meadow in his garden. He divides it into N * M squares. Initially all the squares were covered with grass. He mowed down the grass on some of the squares and th…
题意:有一个n*8的蜂房(6边形的格子),其中部分是障碍格子,其他是有蜂蜜的格子,每次必须走1个圈取走其中的蜂蜜,在每个格子只走1次,且所有蜂蜜必须取走,有多少种取法? 思路: 以前涉及的只是n*m的矩阵,也就是四边形的,现在变成了6边形,那么每个格子也就有6个方向可以出/进.为了方便考虑,将蜂房变成按列来扫,那么轮廓线需要2*n+1个插头信息.这里不需要用到括号表示法或者最小表示法,只需要表示该位置是否有线即可,所以每个插头仅需1个位就可以表示了. 转置一下后的蜂房应该是这样的: 轮廓线是一个…
建议入门的人先看cd琦的<基于连通性状态压缩的动态规划问题>.事半功倍. 插头DP其实是比较久以前听说的一个东西,当初是水了几道水题,最近打算温习一下,顺便看下能否入门之类. 插头DP建议先理解“插头”的概念.然后会HASH表(这个其实是很基础的东西,应该都会的).然后就是DP. 以及特殊题目的特殊处理. 好像一般是求N,M<=12的网格图的某种回路数或某种通路数的方案数. 大体上每个题说几句特殊处理,有问题请纠正....题目的顺序基本上难度递增 另外代码我都是用括号匹配的.因为感觉连通…
/* ural1519 求经过全部可行点的哈密顿回路的个数 括号匹配法,转移有点复杂,可是时间空间比較小 */ #include<cstdio> #include<cstring> #include<string> #include<iostream> #include<algorithm> #include<cmath> #include<map> #include<queue> #define LL lon…
题目大意: 题目背景竟然是dota!屠夫打到大后期就没用了,,只能去吃树! 给一个n*m的地图,有些格子是不可到达的,要把所有可到达的格子的树都吃完,并且要走回路,求方案数 题解: 这题大概是最简单的插头dp了.. 比陈丹琦论文里的例题还要简单,因为允许有多个回路,所以不需要存储插头之间的连通性,直接二进制状压 搞清楚插头和轮廓线的概念基本就可以做出来了 这里有一些资料http://www.docin.com/p-741918386.html 代码: #include <iostream> #…
正题 题目链接:https://www.luogu.com.cn/problem/P3170 题目大意 给出\(n*m\)的网格上有一些障碍,要求用三个\(L\)形(高宽随意,不能退化成线段/点)覆盖格子且\(L\)形之间不能重叠. 求覆盖方案(每个\(L\)形相同) \(2\leq n,m\leq 30\) 解题思路 一道比模板要简单的插头\(dp\)?(当然我依旧不会) 先是考虑插头的状态,每个\(L\)形的话,一个还没有涂完的\(L\)形可能是右插头或者下插头,因为只有三个所以最多只会有\…
最裸的插头dp,可参见大白书. #include<cstdio> #include<cstring> using namespace std; #define MOD 1000000007 int f[2][(1<<5)+10],n,m; int main(){ scanf("%d%d",&n,&m); int cur=0; f[0][(1<<m)-1]=1; for(int i=0;i<n;++i){ for(in…
/* ZOJ 3213 好吧,看过那种括号表示法后,就崩溃了,实在受不了.情况复杂,写了两天,人也有点傻X了,只能放弃,转而用最小表示法. 最小表示法不难写: 1)首先,要承认路径上有格子不选的情况,于是,在00的情况下,可扩展,也可不选. 2)不能出现环,因而不能有L=U的情况出现. 3)以下是模版代码,类同是必然.但转而求路径数的时候,应当去掉不扩展的情况,同时,在IF(L|U)的情况下,亦不必考虑当前是否为最后一个格子, 只需按写的转移即可. 4)增加独立插头时,必须在总的独立插头数小于2…