Link: POJ 1739 传送门 Solution: 这题除了一开始的预处理,基本上就是插头$dp$的模板题了 由于插头$dp$求的是$Hamilton$回路,而此题有起点和终点的限制 于是可以构造一条$[n,1]->[n+2,1]->[n+2,m]->[n,m]$的路径,正好只添加一条$S->T$的路径 接下来就是插头$dp$的模板了 推荐三篇文章,看完基本上就懂插头$dp$了吧, litble:https://blog.csdn.net/litble/article/det…
题意:给一个n*m的矩阵,其中#是障碍格子,其他则是必走的格子,问从左下角的格子走到右下角的格子有多少种方式. 思路: 注意有可能答案是0,就是障碍格子阻挡住了去路. 插头DP有两种比较常见的表示连通信息的方式: (1)最小表示法 (2)括号表示法 本文用括号表示法实现.左括号为1,右括号为2,用两个位来表示.轮廓线上最多需要表示9个插头信息,那么就是18个位即可.插头的状态转移有如下几种: (1)右插头和下插头都是同个方向的括号,则合并他们,再将对应的两外两个半括号给改成一对.比如 ((())…
Description A square township has been divided up into n*m(n rows and m columns) square plots (1<=N,M<=8),some of them are blocked, others are unblocked. The Farm is located in the lower left plot and the Market is located in the lower right plot. T…
题意:从左下角到右下角有多少种走法. 析:特殊处理左下角和右下角即可. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <string> #include <cstdlib> #include <cmath> #include <iostream> #include <cstring>…
http://poj.org/problem?id=1739 题意:n×m的棋盘,'#'是障碍,'.'是空白,求左下角走到右下角且走过所有空白格子的方案数.(n,m<=8) #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; #define BIT(a,b) ((a)<<((b)<<1)) #…
插头DP 楼教主男人八题之一! 要求从左下角走到右下角的哈密顿路径数量. 啊嘞,我只会求哈密顿回路啊……这可怎么搞…… 容易想到:要是把起点和重点直接连上就变成一条回路了……那么我们就连一下~ 我们可以在整张图下面加两行:(例:3*5) 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 1 1 1 1 1 红色的是原来的起点和终点,下面紫色的路径将这两个点连了起来= =然后这题瞬间就变回了Formula 1那题……求哈密顿回路数量,so easy有没有~(其实不这样加也可以做,起点…
poj 2279 Mr. Young's Picture Permutations \(solution:\) 首先摘取一些关键词:(每行不超过它后面的行)(每排学生安排高度从左到右减少)(学生的高度应该从后面到前面减少).这个已经很提示我们轮廓线DP了.而且这一题的数据范围也十分的小:行数不超过五行,人数不多于三十人.这么小的数据范围基本上可以断定是DP了. 然后这种带限制条件的我们可以想办法满足,比如说身高问题我们一般都会采取填人的办法(这一题按身高从大到小填(当然反过来也可以)),然后我们…
亲手写掉的第一道最小表示法!哈哈哈太开心啦~ 不同于以往的几个插头\(dp\),这个题目的轮廓线是周围的一圈\(n\)个格子.而其所谓"插头"也变成了相邻格子的所属连通分量编号,并不是直接把前面几个题的思想往上套就可以轻松解决的了.这里我们就要采用一种叫最小表示法的东西来表示它的连通性信息啦~ (其实感觉是不是称之为逐格递推的轮廓线\(dp\)比较好... 而最小表示法是什么呢?举个例子,现在有这样一个序列\((5,5,3,2,4,1,3,2)\),序列中的每一个数代表第\(i\)个格…
题意: 有一个n*m的矩阵(0<n,m<=12),有部分的格子可种草,有部分不可种,问有多少种不同的种草方案(完全不种也可以算1种,对答案取模后输出)? 思路: 明显的状压DP啦,只是怎样压缩状态?跟轮廓线DP一样,按格子为单位来设计状态,一个状态只需要表示到其上方和左方的格子,所以最多只需要保存min(n,m)个01状态就行了(可以尝试旋转一下矩阵),最多需要12位.用哈希表来做会比较快吧,不用去考虑无效的状态,比如出现相邻两个1. //#include <bits/stdc++.h&…
题意:有一个n*m的棋盘,要求用1*2的骨牌来覆盖满它,有多少种方案?(n<12,m<12) 思路: 由于n和m都比较小,可以用轮廓线,就是维护最后边所需要的几个状态,然后进行DP.这里需要维护的状态数就是min(n,m).即大概是一行的大小.每次放的时候,只考虑(1)以当前格子为右方,进行横放:(2)以当前格子为下方进行竖放:(3)还有就是可以不放. 3种都是不一样的,所以前面的一种状态可能可以转为后面的几种状态,只要满足了条件.条件是,横放时,当前格子不能是最左边的:竖放时,当前格子不能是…