https://www.luogu.org/problemnew/show/P5074

插头 $ dp $ 入门题

如果你还不会插头 $ dp $ 请右转 洛谷插头dp题解

虽然是入门题但还是逃不过分类讨论的魔爪

这里采用了括号序列的方法

$ left $ 表示左插头的状态,$ up $ 表示右插头的状态

情况 1:这个格子不能放线

只有在 $ left == 0 $ && $ up == 0 $ 的时候才能转移

情况 2:$ left == 0 $ && $ up == 0 $

因为每个格子一定要放线,所以要给这个格子加一个下插头和一个右插头

情况 3:$ left == 0 $ && $ up != 0 $

有一个上插头下来,没有左插头,为了让这个插头形成回路,我们给这个插头加一个下插头或者右插头

情况 4:$ left != 0 $ && $ up == 0 $

跟情况 3 类似,这里不再赘述

情况 5:$ left == 1 $ && $ up == 1 $

一个左插头和一个上插头都是左括号,要到右边去找到一个右括号来匹配,并且将右括号变成左括号

个人认为这是最难理解的一种情况,强烈建议大家自己去画个图

情况 6:$ left == 2 $ && $ up == 2 $

根情况 5 类似,只不过变成了到左边找左括号匹配

情况 7:$ left == 2 $ && $ up == 1 $

相当于左插头和上插头抵消了,将这两个插头直接去掉后,左插头本来有一个左括号和它匹配,上插头有一个右括号和它匹配,仍然满足括号序列的性质

情况 8:$ left == 1 $ && $ up == 2 $

形成了一个回路,直接连接即可

当然,如果这个回路是最后一个回路的话要统计答案,判断是否是最后一个回路只需判断这个格子是不是最后一个可以放线的点

最后这个题目有一个小坑,就是当整张地图都不能放线的时候还是算有一种情况的

下面是简(sang)单(xin)明(bing)了(kuang)的代码

#include <bits/stdc++.h>
#define Fast_cin ios::sync_with_stdio(false), cin.tie();
#define For(i, a, b) for(register int i = a; i <= b; i++)
#define Forr(i, a, b) for(register int i = a; i >= b; i--)
#define DEBUG(x) cerr << "DEBUG" << x << " >>> " << endl;
using namespace std; typedef unsigned long long ull;
typedef long long ll; template <typename _T>
inline void read(_T &f) {
f = 0; _T fu = 1; char c = getchar();
while(c < '0' || c > '9') { if(c == '-') fu = -1; c = getchar(); }
while(c >= '0' && c <= '9') { f = (f << 3) + (f << 1) + (c & 15); c = getchar(); }
f *= fu;
} template <typename T>
void print(T x) {
if(x < 0) putchar('-'), x = -x;
if(x < 10) putchar(x + 48);
else print(x / 10), putchar(x % 10 + 48);
} template <typename T>
void print(T x, char t) {
print(x); putchar(t);
} const int mod = 5801, N = mod + 100; ll f[2][N], ans;
int a[15][15], tot[2], v[2][N], nxt[N], head[N], bin[15];
int T, n, m, now, end1, end2; void ins(int zt, ll val) {
int u = zt % mod;
for(register int i = head[u]; i; i = nxt[i])
if(v[now][i] == zt) {
f[now][i] += val;
return;
}
nxt[++tot[now]] = head[u]; head[u] = tot[now];
f[now][tot[now]] = val; v[now][tot[now]] = zt;
} void sol() {
tot[now] = 1; f[now][1] = 1; v[now][1] = 0;
for(register int i = 1; i <= n; i++) {
for(register int j = 1; j <= tot[now]; j++) v[now][j] <<= 2;
for(register int j = 1; j <= m; j++) {
now ^= 1; memset(head, 0, sizeof(head)); tot[now] = 0;
for(register int k = 1; k <= tot[now ^ 1]; k++) {
int zt = v[now ^ 1][k]; ll val = f[now ^ 1][k];
int t1 = (zt >> ((j << 1) - 2)) & 3, t2 = (zt >> (j << 1)) & 3;
if(a[i][j] == 0) {
if(t1 == 0 && t2 == 0) ins(zt, val);
} else if(t1 == 0 && t2 == 0) {
if(a[i][j + 1] && a[i + 1][j]) ins(zt ^ bin[j - 1] ^ (bin[j] << 1), val);
} else if(t1 == 0 && t2 != 0) {
if(a[i][j + 1]) ins(zt, val);
if(a[i + 1][j]) ins(zt ^ (bin[j] * t2) ^ (bin[j - 1] * t2), val);
} else if(t1 != 0 && t2 == 0) {
if(a[i + 1][j]) ins(zt, val);
if(a[i][j + 1]) ins(zt ^ (bin[j] * t1) ^ (bin[j - 1] * t1), val);
} else if(t1 == 1 && t2 == 1) {
int nowv = 1;
for(register int t = j + 1; t < m; t++) {
int t3 = (zt >> (t << 1)) & 3;
if(t3 == 1) nowv++;
if(t3 == 2) nowv--;
if(!nowv) { ins(zt ^ bin[j - 1] ^ bin[j] ^ (bin[t] * 3), val); break; }
}
} else if(t1 == 2 && t2 == 2) {
int nowv = 1;
for(register int t = j - 2; t > 0; t--) {
int t3 = (zt >> (t << 1)) & 3;
if(t3 == 1) nowv--;
if(t3 == 2) nowv++;
if(!nowv) { ins(zt ^ (bin[j - 1] << 1) ^ (bin[j] << 1) ^ (bin[t] * 3), val); break; }
}
} else if(t1 == 2 && t2 == 1) {
ins(zt ^ (bin[j - 1] << 1) ^ bin[j], val);
} else if(i == end1 && j == end2) {
ans += val;
} else ins(zt ^ bin[j - 1] ^ (bin[j] << 1), val);
}
}
}
} int main() {
read(T); bin[0] = 1;
for(register int i = 1; i <= 11; i++) bin[i] = bin[i - 1] << 2;
for(register int Case = 1; Case <= T; Case++) {
memset(a, 0, sizeof(a));
read(n); read(m); ans = 0; end1 = end2 = 0;
for(register int i = 1; i <= n; i++) {
for(register int j = 1; j <= m; j++) {
read(a[i][j]);
if(a[i][j]) end1 = i, end2 = j;
}
}
if(!end1) { print(1, '\n'); continue; }
sol(); print(ans, '\n');
}
return 0;
}

luoguP5074 Eat the Trees的更多相关文章

  1. HDU 1693 Eat the Trees(插头DP、棋盘哈密顿回路数)+ URAL 1519 Formula 1(插头DP、棋盘哈密顿单回路数)

    插头DP基础题的样子...输入N,M<=11,以及N*M的01矩阵,0(1)表示有(无)障碍物.输出哈密顿回路(可以多回路)方案数... 看了个ppt,画了下图...感觉还是挺有效的... 参考 ...

  2. 【HDU】1693 Eat the Trees

    http://acm.hdu.edu.cn/showproblem.php?pid=1693 题意:n×m的棋盘求简单回路(可以多条)覆盖整个棋盘的方案,障碍格不许摆放.(n,m<=11) #i ...

  3. HDU 1693 Eat the Trees(插头DP)

    题目链接 USACO 第6章,第一题是一个插头DP,无奈啊.从头看起,看了好久的陈丹琦的论文,表示木看懂... 大体知道思路之后,还是无法实现代码.. 此题是插头DP最最简单的一个,在一个n*m的棋盘 ...

  4. HDU 1693 Eat the Trees

    第一道(可能也是最后一道)插头dp.... 总算是领略了它的魅力... #include<iostream> #include<cstdio> #include<cstr ...

  5. 【HDOJ】【1693】Eat The Trees

    插头DP 插头dp模板题…… 这题比CDQ论文上的例题还要简单……因为不用区分左右插头(这题可以多回路,并不是一条哈密尔顿路) 硬枚举当前位置的状态就好了>_< 题解:http://blo ...

  6. Eat the Trees hdu 1693

    Problem DescriptionMost of us know that in the game called DotA(Defense of the Ancient), Pudge is a ...

  7. HDU - 1693 Eat the Trees(多回路插头DP)

    题目大意:要求你将全部非障碍格子都走一遍,形成回路(能够多回路),问有多少种方法 解题思路: 參考基于连通性状态压缩的动态规划问题 - 陈丹琦 下面为代码 #include<cstdio> ...

  8. HDU1693 Eat the Trees 插头dp

    原文链接http://www.cnblogs.com/zhouzhendong/p/8433484.html 题目传送门 - HDU1693 题意概括 多回路经过所有格子的方案数. 做法 最基础的插头 ...

  9. 【HDU1693】Eat the Trees(插头dp)

    [HDU1693]Eat the Trees(插头dp) 题面 HDU Vjudge 大概就是网格图上有些点不能走,现在要找到若干条不相交的哈密顿回路使得所有格子都恰好被走过一遍. 题解 这题的弱化版 ...

随机推荐

  1. oracle中bulk collect into用法

    通过bulk collect减少loop处理的开销 采用bulk collect可以将查询结果一次性地加载到collections中. 而不是通过cursor一条一条地处理. 可以在select in ...

  2. UNITY 打APK是如何确定哪些资源有用哪些无用的

    一切从build settings开始,它即是 构建列表,构建运行包当然从它开始. 1,只有在构建列表中的场景和场景引用资源才会被打进包里,其它资源除了2,3位置都不会被打包 2,streamming ...

  3. 有道笔记链接地址 -----关于python

    一.python相关 python列表的操作[list[]]:     http://note.youdao.com/noteshare?id=93922f3174b1d8fac04514064656 ...

  4. oracle 导入导出指定表

    导出 exp username/password@127.0.0.1/orcl file=D:\xxx.dmp tables(tablename,tablename) 导入 imp username/ ...

  5. LevelDB Compaction操作

    [LevelDB Compaction操作] 对于LevelDb来说,写入记录操作很简单,删除记录仅仅写入一个删除标记就算完事,但是读取记录比较复杂,需要在内存以及各个层级文件中依照新鲜程度依次查找, ...

  6. jsp中常用的标签

    jsp本质上就是一个servlet,只是tomcat会将其翻译成servlet,servlet本质上是一个类,那么jsp也是一个类.jsp中各种标签都会被tomcat翻译成各种基本的java代码 如果 ...

  7. C# \/date(1498820611133+0800)\/ 转DateTime

    开发中经常遇到日期转换问题,特别是做接口的时候,现在整理了下时间戳转为C#格式时间的方法: /// <summary> /// 时间戳转为C#格式时间 /// </summary&g ...

  8. react-native 打包 出apk

    先上步骤: 一. 生成签名文件(my-release-key.keystore文件) Android要求所有应用都有一个数字签名才会被允许安装在用户手机上 1.  在项目目录下运行如下命令: keyt ...

  9. java 线程之对象的同步和异步

    一.多线程环境下的同步与异步 同步:A线程要请求某个资源,但是此资源正在被B线程使用中,因为同步机制存在,A线程请求不到,怎么办,A线程只能等待下去. package com.jalja.org.th ...

  10. 🔸RU大神手册上要再“做”的题🔸