题目链接: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. Linux 下运行 C++ 程序出现 “段错误(核心已转储)”

    Linux下写C++程序出现“段错误(核心已转储)”的问题: 段错误一般就是指访问的内存超出了系统所给这个程序的内存空间,通常这个值是由gdtr来保存的,他是一个48位的寄存器,其中的32位是保存由它 ...

  2. 修改系统dpi

    系统dpi设置不合理,会导致屏幕显示效果差.配置系统dpi设置ro.sf.lcd_density的值即可,不同项目设置位置不同,以高通为例:需要修改 项目/device/qcom/common/roo ...

  3. Find that single one.(linear runtime complexity0

    public class Solution { public int singleNumber(int[] nums) { int temp = 0; for (int i=0;i<nums.l ...

  4. css3 nth-child 与 nth-of-type 的区别

    by zhangxinxu from http://www.zhangxinxu.com本文地址:http://www.zhangxinxu.com/wordpress/?p=1709 一.深呼吸,直 ...

  5. R必学包之dplyr

    http://www.360doc.com/content/17/1204/10/50223086_709726679.shtml

  6. (7)ASP.NET WEB服务器控件

    1. <body> <form id="form1" runat="server"> <div> <asp:Label ...

  7. 实现TTCP (检测TCP吞吐量)

    实现TTCP (检测TCP吞吐量) 应用层协议 为了解决TCP粘包问题以及客户端阻塞问题 设计的应用层协议如下: //告知要发送的数据包个数和长度 struct SessionMessage { in ...

  8. C#/.NET基于Topshelf创建Windows服务的守护程序作为服务启动的客户端桌面程序不显示UI界面的问题分析和解决方案

    本文首发于:码友网--一个专注.NET/.NET Core开发的编程爱好者社区. 文章目录 C#/.NET基于Topshelf创建Windows服务的系列文章目录: C#/.NET基于Topshelf ...

  9. Spring的依赖注入概述

    以下内容引用自http://wiki.jikexueyuan.com/project/spring/dependency-injection.html: 每个基于Java应用程序都有几个对象,这些对象 ...

  10. 关于时间,日期,星期,月份的算法(Java中Calendar的使用方法)

    原文:http://www.open-open.com/code/view/1446195787257 package cn.outofmemory.codes.Date; import java.u ...