题目链接:https://vjudge.net/problem/HDU-1964

Pipes

Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 987    Accepted Submission(s): 494

Problem Description
The construction of office buildings has become a very standardized task. Pre-fabricated modules are combined according to the customer’s needs, shipped from a faraway factory, and assembled on the construction site. However, there are still some tasks that require careful planning, one example being the routing of pipes for the heating system.

Amodern office building ismade up of squaremodules, one on each floor being a service module from which (among other things) hot water is pumped out to the other modules through the heating pipes. Each module (including the service module) will have heating pipes connecting it to exactly two of its two to four neighboring modules. Thus, the pipes have to run in a circuit, from the service module, visiting each module exactly once, before finally returning to the service module. Due to different properties of the modules, having pipes connecting a pair of adjacent modules comes at different costs. For example, some modules are separated by thick walls, increasing the cost of laying pipes. Your task is to, given a description of a floor of an office building, decide the cheapest way to route the heating pipes.

 
Input
The first line of input contains a single integer, stating the number of floors to handle. Then follow n floor descriptions, each beginning on a new line with two integers, 2 <= r <= 10 and 2 <= c <= 10, defining the size of the floor – r-by-c modules. Beginning on the next line follows a floor description in ASCII format, in total 2r + 1 rows, each with 2c + 2 characters, including the final newline. All floors are perfectly rectangular, and will always have an even number of modules. All interior walls are represented by numeric characters, ’0’ to ’9’, indicating the cost of routing pipes through the wall (see sample input).
 
Output
For each test case, output a single line with the cost of the cheapest route.
 
Sample Input
3
4 3
#######
# 2 3 #
#1#9#1#
# 2 3 #
#1#7#1#
# 5 3 #
#1#9#1#
# 2 3 #
#######
4 4
#########
# 2 3 3 #
#1#9#1#4#
# 2 3 6 #
#1#7#1#5#
# 5 3 1 #
#1#9#1#7#
# 2 3 0 #
#########
2 2
#####
# 1 #
#2#3#
# 4 #
#####
 
Sample Output
28
45
10
 
Source
 
Recommend
wangye

题意:

给出一个n*m(n、m<=10)的棋盘,对于一个格子,分别给出它与四个方向相连所需要的花费(即打穿这堵墙所需的花费),求一个回路使得这个回路经过所有的格子刚好一次,且花费是最小的,输出最小花费。

题解:

与此题(URAL1519 Formula 1)无异,只不过把统计个数改成求最小值。

代码如下:

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
using namespace std;
typedef long long LL;
const int INF = 2e9;
const LL LNF = 9e18;
const int MOD = 1e9+;
const int MAXN = 1e5;
const int HASH = 1e4; int n, m, last_x, last_y;
bool maze[][];
int down_cost[][], ri_cost[][]; struct
{
int size, head[HASH], next[MAXN];
LL state[MAXN];
int cost[MAXN]; void init()
{
size = ;
memset(head, -, sizeof(head));
} void insert(LL status, int Cost)
{
int u = status%HASH;
for(int i = head[u]; i!=-; i = next[i])
{
if(state[i]==status)
{
cost[i] = min(cost[i], Cost);
return;
}
}
state[size] = status;
cost[size] = Cost;
next[size] = head[u];
head[u] = size++;
} }Hash_map[]; struct
{
int code[];
LL encode(int m)
{
LL status = ;
int id[], cnt = ;
memset(id, -, sizeof(id));
id[] = ;
for(int i = m; i>=; i--)
{
if(id[code[i]]==-) id[code[i]] = ++cnt;
code[i] = id[code[i]];
status <<= ;
status += code[i];
}
return status;
} void decode(int m, LL status)
{
memset(code, , sizeof(code));
for(int i = ; i<=m; i++)
{
code[i] = status&;
status >>= ;
}
} void shift(int m)
{
for(int i = m-; i>=; i--)
code[i+] = code[i];
code[] = ;
} }Line; //插头的花费在新建的时候加进去
void transfer(int i, int j, int cur)
{
for(int k = ; k<Hash_map[cur].size; k++)
{
LL status = Hash_map[cur].state[k];
LL Cost = Hash_map[cur].cost[k];
Line.decode(m, status);
int up = Line.code[j];
int left = Line.code[j-]; if(!up && !left)
{
if(maze[i+][j] && maze[i][j+])
{
Line.code[j] = Line.code[j-] = ; //最多只有5个连通分量
Hash_map[cur^].insert(Line.encode(m), Cost+down_cost[i][j]+ri_cost[i][j]);
}
}
else if( (left&&!up) || (!left&&up) )
{
int line = left?left:up;
if(maze[i][j+])
{
Line.code[j-] = ;
Line.code[j] = line;
Hash_map[cur^].insert(Line.encode(m), Cost+ri_cost[i][j]);
}
if(maze[i+][j])
{
Line.code[j-] = line;
Line.code[j] = ;
if(j==m) Line.shift(m);
Hash_map[cur^].insert(Line.encode(m), Cost+down_cost[i][j]);
}
}
else
{
if(up!=left)
{
Line.code[j] = Line.code[j-] = ;
for(int t = ; t<=m; t++)
if(Line.code[t]==up)
Line.code[t] = left;
if(j==m) Line.shift(m);
Hash_map[cur^].insert(Line.encode(m), Cost);
}
else if(i==last_x && j==last_y)
{
Line.code[j] = Line.code[j-] = ;
if(j==m) Line.shift(m);
Hash_map[cur^].insert(Line.encode(m), Cost);
}
}
}
} int main()
{
int T;
char str[];
scanf("%d", &T);
while(T--)
{
scanf("%d%d", &n, &m); getchar();
memset(maze, false, sizeof(maze));
for(int i = ; i<=n; i++)
for(int j = ; j<=m; j++)
maze[i][j] = true; gets(str);
for(int i = ; i<n; i++)
{
gets(str);
for(int j = ; j<m; j++)
ri_cost[i][j] = str[j*] - '';
gets(str);
for(int j = ; j<=m; j++)
down_cost[i][j] = str[j*-] - '';
}
gets(str);
for(int j = ; j<m; j++)
ri_cost[n][j] = str[j*] - '';
gets(str);
last_x = n;
last_y = m; int cur = ;
Hash_map[cur].init();
Hash_map[cur].insert(, );
for(int i = ; i<=n; i++)
for(int j = ; j<=m; j++)
{
Hash_map[cur^].init();
transfer(i, j, cur);
cur ^= ;
} LL last_status = ;
LL ans = Hash_map[cur].size?Hash_map[cur].cost[last_status]:;
printf("%d\n", ans);
}
}

HDU1964 Pipes —— 插头DP的更多相关文章

  1. hdu1964之插头DP求最优值

    Pipes Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Subm ...

  2. 插头DP专题

    建议入门的人先看cd琦的<基于连通性状态压缩的动态规划问题>.事半功倍. 插头DP其实是比较久以前听说的一个东西,当初是水了几道水题,最近打算温习一下,顺便看下能否入门之类. 插头DP建议 ...

  3. 插头dp练习

    最近学了插头dp,准备陆续更新插头dp类练习. 学习论文还是cdq那篇<基于连通性状态压缩的动态规划问题>. 基本的想法都讲得很通透了,接下来就靠自己yy了. 还有感谢kuangbin大大 ...

  4. 插头dp

    插头dp 感受: 我觉得重点是理解,算法并不是直接想出怎样由一种方案变成另一种方案.而是方案本来就在那里,我们只是枚举状态统计了答案. 看看cdq的讲义什么的,一开始可能觉得状态很多,但其实灰常简单 ...

  5. HDU 4113 Construct the Great Wall(插头dp)

    好久没做插头dp的样子,一开始以为这题是插头,状压,插头,状压,插头,状压,插头,状压,无限对又错. 昨天看到的这题. 百度之后发现没有人发题解,hust也没,hdu也没discuss...在acm- ...

  6. HDU 4949 Light(插头dp、位运算)

    比赛的时候没看题,赛后看题觉得比赛看到应该可以敲的,敲了之后发现还真就会卡题.. 因为写完之后,无限TLE... 直到后来用位运算代替了我插头dp常用的decode.encode.shift三个函数以 ...

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

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

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

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

  9. HDU 4064 Carcassonne(插头DP)(The 36th ACM/ICPC Asia Regional Fuzhou Site —— Online Contest)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4064 Problem Description Carcassonne is a tile-based ...

随机推荐

  1. Spoj-VISIBLEBOX Decreasing Number of Visible Box

    Shadowman loves to collect box but his roommates woogieman and itman don't like box and so shadowman ...

  2. EC++学习笔记(六) 继承和面向对象设计

    条款32:确定你的 public 继承塑模出 is-a 关系 public inheritance 意味着 is-a 关系class Derived 以 public 形式继承 class Base, ...

  3. 标准C程序设计七---22

    Linux应用             编程深入            语言编程 标准C程序设计七---经典C11程序设计    以下内容为阅读:    <标准C程序设计>(第7版) 作者 ...

  4. TortoiseSVN如何更换或重置登录用户

    昨天手贱把svn重新卸载了,再安装后便与之前的项目断了,因为第一次使用这个,也不清楚再怎么登录,还有就是上次是使用别人的账号,也不知道怎么清除别人的账号. 鼠标右键找到settings,点击打开 找到 ...

  5. Java对象的死亡

    在堆里面存放着Java世界中几乎所有的对象实例,垃圾收集器在对堆进行回收前,第一件事情就是要确定这些对象之中哪些还“存活”着,哪些已经“死去”(即不可能再被任何途径使用的对象). 一,引用计数算法 给 ...

  6. [转]gzip,bzip2,tar,zip命令使用方法详解

    原文:http://blog.chinaunix.net/uid-20779720-id-2547669.html 1 gzipgzip(1) 是GNU的压缩程序.它只对单个文件进行压缩.基本用法如下 ...

  7. 基于源码学习-fighting

    今天逛着逛着,看到个培训网站,点进去和客服人员聊了一下.接着,看了看他们的培训课程,想了解一下 嵌入式开发的. (人就是要放空自己,把自己当做什么都不会,当着个婴儿[小学生]一般认真,要学什么知识就是 ...

  8. annotation使用示例

    annotation使用示例 学习了:https://www.imooc.com/learn/456 Annotation编写规则:@Target,@Retention,设置一些String.int属 ...

  9. MapReduce编程实战之“调试”和&quot;调优&quot;

    本篇内容 在上一篇的"初识"环节,我们已经在本地和Hadoop集群中,成功的执行了几个MapReduce程序,对MapReduce编程,已经有了最初的理解. 在本篇文章中,我们对M ...

  10. 我理解的ios和android

    近期着手了几个android和ios的项目,如今说下我的几个对他们的理解 从设计上来讲.我觉得android 它更像是个网页,一个页面跳到另外一个页面,两者之间的关联不是非常大,仅仅能传递一些简单的參 ...