http://poj.org/problem?id=3133

考虑插头 dp

用四进制表示一个插头的状态,0 表示没有插头,2 表示这个插头是连接两个 2 的,3 同理

然后就是大力分类讨论了

这题还是比较友善的一题,思路相对来说简单很多

我写的括号序列的方法状态是满的,数组必须开到 $ 3 ^ 9 $ 才能过

#include <cstdio>
#include <cstring>
#include <algorithm>
#define CIOS ios::sync_with_stdio(false);
#define rep(i, a, b) for(register int i = a; i <= b; i++)
#define per(i, a, b) for(register int i = a; i >= b; i--)
#define DEBUG(x) cerr << "DEBUG" << x << " >>> ";
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 = 19687, N = mod + 50, INF = 0x7fffffff; int a[15][15], bin[15], f[2][N], v[2][N], head[N], tot[2], nxt[N], n, m, now; // 状态只有 0, 2, 3, 表示没有插头, 2 插头和 3 插头 void ins(int zt, int val) {
int u = zt % mod;
for(register int i = head[u]; i; i = nxt[i])
if(v[now][i] == zt) {
f[now][i] = min(f[now][i], val);
return;
}
nxt[++tot[now]] = head[u]; head[u] = tot[now];
v[now][tot[now]] = zt; f[now][tot[now]] = val;
} void sol() {
tot[now] = 1; f[now][1] = v[now][1] = 0;
for(register int i = 1; i <= n; i++) {
for(register int i = 1; i <= tot[now]; i++) v[now][i] <<= 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], val = f[now ^ 1][k];
int left = (zt >> ((j << 1) - 2)) & 3, up = (zt >> (j << 1)) & 3;
int right = (j == m) ? 1 : a[i][j + 1], down = (i == n) ? 1 : a[i + 1][j];
if(a[i][j] == 1) {
if(!left && !up) ins(zt, val);
} else if(!left && !up) {
if(!a[i][j]) {
ins(zt, val);
if(right + down == 5 || right == 1 || down == 1) continue;
if(right == 2 || down == 2) {
// 当两边有 2 插头时, 向下和向右摆 2 插头
ins(zt ^ (bin[j - 1] << 1) ^ (bin[j] << 1), val + 1);
} else if(right == 3 || down == 3) {
ins(zt ^ (bin[j - 1] * 3) ^ (bin[j] * 3), val + 1);
} else {
ins(zt ^ (bin[j - 1] << 1) ^ (bin[j] << 1), val + 1);
ins(zt ^ (bin[j - 1] * 3) ^ (bin[j] * 3), val + 1);
}
} else {
// 当前位置是一个 2 或 3
if(a[i][j] + right != 5 && right != 1) {
ins(zt ^ (bin[j] * a[i][j]), val + 1);
}
if(a[i][j] + down != 5 && down != 1) {
ins(zt ^ (bin[j - 1] * a[i][j]), val + 1);
}
}
} else if(left && up) {
if(left + up == 5 || a[i][j]) continue;
ins(zt ^ (bin[j - 1] * left) ^ (bin[j] * up), val + 1);
} else if(left && !up) {
if(a[i][j] == 0) {
if(right == 0 || right == left) ins(zt ^ (bin[j - 1] * left) ^ (bin[j] * left), val + 1);
if(down == 0 || down == left) ins(zt, val + 1);
} else if(a[i][j] == left) {
ins(zt ^ (bin[j - 1] * left), val + 1);
}
} else if(!left && up) {
if(a[i][j] == 0) {
if(right == 0 || right == up) ins(zt, val + 1);
if(down == 0 || down == up) ins(zt ^ (bin[j] * up) ^ (bin[j - 1] * up), val + 1);
} else if(a[i][j] == up) {
ins(zt ^ (bin[j] * up), val + 1);
}
}
}
}
}
} int main() {
bin[0] = 1; for(register int i = 1; i <= 11; i++) bin[i] = bin[i - 1] << 2;
while(scanf("%d %d", &n, &m) == 2 && n && m) {
memset(a, 0, sizeof(a)); memset(head, 0, sizeof(head)); memset(tot, 0, sizeof(tot));
for(register int i = 1; i <= n; i++) {
for(register int j = 1; j <= m; j++) read(a[i][j]);
}
sol(); int ans = INF;
for(register int i = 1; i <= tot[now]; i++) ans = min(ans, f[now][i]);
if(ans == INF) ans = 2; print(ans - 2, '\n');
}
return 0;
}

poj 3133 Manhattan Wiring的更多相关文章

  1. POJ 3133 Manhattan Wiring (插头DP,轮廓线,经典)

    题意:给一个n*m的矩阵,每个格子中有1个数,可能是0或2或3,出现2的格子数为2个,出现3的格子数为2个,要求将两个2相连,两个3相连,求不交叉的最短路(起终点只算0.5长,其他算1). 思路: 这 ...

  2. 【POJ】3133 Manhattan Wiring

    http://poj.org/problem?id=3133 题意:n×m的网格,有2个2,2个3,他们不会重合.还有障碍1.现在求2到2的路径和3到3的路径互不相交的最短长度-2.(2<=n, ...

  3. poj3133 Manhattan Wiring

    Manhattan Wiring Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 2016   Accepted: 1162 ...

  4. [LA3620]Manhattan Wiring

    [LA3620]Manhattan Wiring 试题描述 输入 输出 输入示例 输出示例 数据规模及约定 见“输入” 题解 我们把“连线”的过程改为“铺地砖”的过程,总共有 11 种地砖,每种地砖上 ...

  5. 【poj3133】 Manhattan Wiring

    http://poj.org/problem?id=3133 (题目链接) 题意 $n*m$的网格里有空格和障碍,还有两个$2$和两个$3$.要求把这两个$2$和两个$3$各用一条折线连起来.障碍里不 ...

  6. poj 1806 Manhattan 2025

    点击打开链接 题目大意就是给定一个最大歩数,让你输出你在三维的空间中可以到达的位置的切片,注意当歩数大于9的时候就不需要输出了! #include<stdio.h> #include< ...

  7. uva1214 Manhattan Wiring 插头DP

    There is a rectangular area containing n × m cells. Two cells are marked with “2”, and another two w ...

  8. [Poj3133]Manhattan Wiring (插头DP)

    Description 题目大意:给你个N x M(1≤N, M≤9)的矩阵,0表示空地,1表示墙壁,2和3表示两对关键点.现在要求在两对关键点之间建立两条路径,其中两条路径不可相交或者自交(就是重复 ...

  9. caioj1496: [视频]基于连通性状态压缩的 动态规划问题:Manhattan Wiring

    %%%%orz苏大佬 虽然苏大佬的baff吸不得,苏大佬的梦信不得,但是膜苏大佬是少不得的囧 这题还是比较有收获的 哼居然有我不会做的插头DP 自己yy了下,2表示属于2的插头,3表示3的插头 假如当 ...

随机推荐

  1. 通过nginx + lua来统计nginx上的监控网络请求和性能

    介绍 以前我们为nginx做统计,都是通过对日志的分析来完成.比较麻烦,现在基于ngx_lua插件,开发了实时统计站点状态的脚本,解放生产力. 项目主页: https://github.com/sky ...

  2. SpringMVC 中xml 配置多数据源

    1,配置jdbc.properties jdbc.driver_one=... jdbc.url_one=..... jdbc.username_one=... jdbc.password_one=. ...

  3. PHP 将HTML转成PDF文件,HTML 转word,Word 转Html

    html转 PDF 用MPDF ,Word转Html  纯PHP的方法暂未找到Word直接转PDF的方法 可以使用 LibreOffice 6.1  (Liunx,win) 皆可使用 Html转成PD ...

  4. selenium IDE测试中的坑

    selenium IDE工具是firefox自带的一个网页自动化测试工具,因为它是IDE所以它很方便使用,但也因为它是IDE所以它有那么些坑. 问题:selenium回放中timeout问题 网页的打 ...

  5. c语言静态断言

    在php中可以通过xdebug来显示详细的错误信息,可以细化到哪个文件哪行代码引起的报错.在C语言里面也可以通过静态断言(assert)来使得调试代码更加方便.关于断言,可以作为一种很强大的调试方式或 ...

  6. 多因子降维法(MDR,Multifactor Dimensionality Reduction )

    多因子降维法(MDR,multifactor dimensionality reduction)   多因子降维法(MDR,Multifactor Dimensionality Reduction ) ...

  7. 静态方法调静态属性用self,$this不可以

  8. msdn 硬盘

    https://msdn.microsoft.com/library/windows/hardware/ff566204 Returns the ATA-2 identify data, the Se ...

  9. C#使用互斥量(Mutex)实现多进程并发操作时多进程间线程同步操作(进程同步)的简单示例代码及使用方法

    本文主要是实现操作系统级别的多进程间线程同步(进程同步)的示例代码及测试结果.代码经过测试,可供参考,也可直接使用. 承接上一篇博客的业务场景[C#使用读写锁三行代码简单解决多线程并发写入文件时线程同 ...

  10. 前端福利之overflow-scrol 怎么隐藏滚动条(转)

    最近用vue写wap站的时候遇到了微信打开页面滚动条无法隐藏的问题. 对于隐藏滚动条,我们最常用的方法首先是: 1.使用以下CSS可以隐藏滚动条: .container::-webkit-scroll ...