[LA3620]Manhattan Wiring

试题描述

输入

输出

输入示例


输出示例


数据规模及约定

见“输入

题解

我们把“连线”的过程改为“铺地砖”的过程,总共有 11 种地砖,每种地砖上的图案连接了两个不同的边界,或只触碰了一个边界,或没有图案,具体见下图:

其中,有障碍的格子只能铺 0 号砖,有数字 2 或 3 的格子只能铺 1 到 4 号砖,空地可以铺 0 或 5 到 10 号砖。

然后我们就可以轮廓线 dp 了,把状态表示成上一行的底部是否有线,这一行的底部是否有线,当前格子的左边是否有线,具体见下图:

带绿点的格子表示当前格子。那么上图的状态就是 (02000100)3 了(我习惯先读上面一行,再读下面一行,最后读竖直边上的数字),注意这里 2 连出的线与 3 连出的线进行了区分,因为不能让 2 和 3 连到一起。

转移的时候需要判断一些不合法情况:线头接到了没有线头和它相连的地方,不同类型线头接在了一起,或是有一个线头等你去接而你没有理它。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
using namespace std; const int BufferSize = 1 << 16;
char buffer[BufferSize], *Head, *Tail;
inline char Getchar() {
if(Head == Tail) {
int l = fread(buffer, 1, BufferSize, stdin);
Tail = (Head = buffer) + l;
}
return *Head++;
}
int read() {
int x = 0, f = 1; char c = Getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = Getchar(); }
while(isdigit(c)){ x = x * 10 + c - '0'; c = Getchar(); }
return x * f;
} #define maxn 15
#define maxs 59060
#define maxb 11
#define oo 2147483647 struct Blo {
bool L, U, R, D; int v;
Blo() {}
Blo(bool _l, bool _u, bool _r, bool _d, int _v): L(_l), U(_u), R(_r), D(_d), v(_v) {}
} bls[maxb];
int n, m, Map[maxn][maxn], f[maxn][maxn][maxs], tri[maxn]; void up(int& a, int b) {
a = min(a, b);
return ;
} char str[maxn];
char* tri_(int x) {
int l = 0;
while(x) str[l++] = x % 3 + '0', x /= 3;
while(l <= m) str[l++] = '0';
str[l] = 0;
return str;
} int main() {
bls[0] = Blo(0, 0, 0, 0, 0);
bls[1] = Blo(1, 0, 0, 0, 1);
bls[2] = Blo(0, 1, 0, 0, 1);
bls[3] = Blo(0, 0, 1, 0, 1);
bls[4] = Blo(0, 0, 0, 1, 1);
bls[5] = Blo(1, 1, 0, 0, 2);
bls[6] = Blo(1, 0, 1, 0, 2);
bls[7] = Blo(1, 0, 0, 1, 2);
bls[8] = Blo(0, 1, 1, 0, 2);
bls[9] = Blo(0, 1, 0, 1, 2);
bls[10] = Blo(0, 0, 1, 1, 2);
tri[0] = 1;
for(int i = 1; i < maxn; i++) tri[i] = tri[i-1] * 3; while(1) {
n = read(); m = read();
if(!n && !m) break; for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++) Map[i][j] = read();
int all = tri[m+1] - 1;
for(int i = 1; i <= n + 1; i++)
for(int j = 1; j <= m; j++)
for(int S = 0; S <= all; S++) f[i][j][S] = oo;
f[1][1][0] = 0;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
for(int S = 0; S <= all; S++) if(f[i][j][S] < oo) {
// printf("%d %d %s: %d\n", i, j, tri_(S), f[i][j][S]);
if(Map[i][j] == 1) {
if(S % 3 || S / tri[m]) continue;
if(j < m) up(f[i][j+1][S/3%tri[m-1]], f[i][j][S] + bls[0].v);
else up(f[i+1][1][S/3%tri[m-1]], f[i][j][S] + bls[0].v);
}
if(Map[i][j] == 2) {
for(int c = 1; c <= 4; c++) {
if(S % 3 > 0 ^ bls[c].U > 0) continue;
if(S % 3 && S % 3 != 1) continue;
if(S / tri[m] > 0 ^ bls[c].L > 0) continue;
if(S / tri[m] && S / tri[m] != 1) continue;
if(j == m && bls[c].R) continue;
int tS = S / 3 % tri[m-1] + (int)bls[c].D * tri[m-1] + (int)bls[c].R * tri[m];
if(j < m) up(f[i][j+1][tS], f[i][j][S] + bls[c].v);
else up(f[i+1][1][tS], f[i][j][S] + bls[c].v);
}
}
if(Map[i][j] == 3) {
for(int c = 1; c <= 4; c++) {
if(S % 3 > 0 ^ bls[c].U > 0) continue;
if(S % 3 && S % 3 != 2) continue;
if(S / tri[m] > 0 ^ bls[c].L > 0) continue;
if(S / tri[m] && S / tri[m] != 2) continue;
if(j == m && bls[c].R) continue;
int tS = S / 3 % tri[m-1] + (int)bls[c].D * 2 * tri[m-1] + (int)bls[c].R * 2 * tri[m];
if(j < m) up(f[i][j+1][tS], f[i][j][S] + bls[c].v);
else up(f[i+1][1][tS], f[i][j][S] + bls[c].v);
}
}
if(!Map[i][j]) {
for(int c = 0; c <= 10; c ? c++ : (c = 5)) {
int tp = 0;
if(S % 3 > 0 ^ bls[c].U > 0) continue;
if(S % 3) tp = S % 3;
if(S / tri[m] > 0 ^ bls[c].L > 0) continue;
if(S / tri[m] && tp && S / tri[m] != tp) continue;
if(S / tri[m]) tp = S / tri[m];
if(j == m && bls[c].R) continue;
if(tp) {
int tS = S / 3 % tri[m-1] + (int)bls[c].D * tp * tri[m-1] + (int)bls[c].R * tp * tri[m];
if(j < m) up(f[i][j+1][tS], f[i][j][S] + bls[c].v);
else up(f[i+1][1][tS], f[i][j][S] + bls[c].v);
}
else for(tp = 1; tp <= 2; tp++) {
int tS = S / 3 % tri[m-1] + (int)bls[c].D * tp * tri[m-1] + (int)bls[c].R * tp * tri[m];
if(j < m) up(f[i][j+1][tS], f[i][j][S] + bls[c].v);
else up(f[i+1][1][tS], f[i][j][S] + bls[c].v);
}
}
}
} printf("%d\n", f[n+1][1][0] < oo ? (f[n+1][1][0] >> 1) : 0);
} return 0;
}

代码贼难写。。。QAQ

[LA3620]Manhattan Wiring的更多相关文章

  1. poj3133 Manhattan Wiring

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

  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

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

  4. poj 3133 Manhattan Wiring

    http://poj.org/problem?id=3133 考虑插头 dp 用四进制表示一个插头的状态,0 表示没有插头,2 表示这个插头是连接两个 2 的,3 同理 然后就是大力分类讨论了 这题还 ...

  5. uva1214 Manhattan Wiring 插头DP

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

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

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

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

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

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

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

  9. 别人整理的DP大全(转)

    动态规划 动态规划 容易: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ...

随机推荐

  1. android sdk更新失败的解决方法

    [解决方法] 选择Tools-Options,在弹出的设置窗口中,「HTTP Proxy Server」和「HTTP Proxy Port」输入框内填入mirrors.neusoft.edu.cn和8 ...

  2. Azure 8 月新公布

    Azure 8 月新发布:Cosmos DB 每分钟请求单位,存储的托管磁盘及促销,高级和标准磁盘存储大尺寸磁盘,高级磁盘存储小尺寸磁盘. Azure Cosmos DB:每分钟请求单位为您降低成本, ...

  3. 最近在准备面试,总结了几个java中面向对象的几个问题,问题本事还不够全面,要想知道还是要自己去找,但是在面试上应该是没多大问题了

    Overload(重载)与Override(重写)的区别 重载:发生在一个类中,方法名称相同,参数列表不同,方法体不同(看对象类型) 重写:发生在父类中,方法名称相同,参数列表相同,方法体不同(看引用 ...

  4. Core Foundation 框架

    Core Foundation框架 (CoreFoundation.framework) 是一组C语言接口,它们为iOS应用程序提供基本数据管理和服务功能.下面列举该框架支持进行管理的数据以及可提供的 ...

  5. MYSQL - 限制资源的使用

    MYSQL - 限制资源的使用 1.MAX_QUERIES_PER_HOUR 用来限制用户每小时运行的查询数量 mysql> grant select on *.* to 'cu_blog'@' ...

  6. awk日志分割

    awk日志分割 1. awk实现日志按照日期分割 #!/bin/bash DATE=$(date -d yesterday +%Y-%m-%d) awk  'BEGIN{RS="'$DATE ...

  7. 洛谷 P2032 扫描

    https://www.luogu.org/problemnew/show/P2032 为啥不用STL,多方便. 定义一个大根堆,里边放一对数,这个数的大小和位置. 我们对于每次查询,判断首元素的位置 ...

  8. (7)zabbix资产清单inventory管理

    概述 监控的设备越来越多,有时候搞不清楚哪台服务器是什么配置,大多公司有自己的资产清单,要去专门的系统查询显得多少有点麻烦.为此,zabbix专门设置了设备资产管理功能. 我们创建或编辑主机的时候,可 ...

  9. Python Third Day-函数

    ''' 为什么要有函数?没有函数带来的困扰? 组织结构不清晰,可读性差 代码冗余 可扩展性差 什么是函数 具备某一个功能的工具--->函数 事先准备工具->函数的定义 拿来就用.重复使用- ...

  10. Verilog之delay的两种用法(inter/intra)

    verilog语言中有两种延迟方式:inter-delay和intra-delay,关于inter和intra.这两个英文前缀都有“内部,之间”的意思,但又有所不同.inter表达不同事物之间,int ...