POJ3133(插头dp)
Time Limit: 5000MS | Memory Limit: 65536K | |
Description
There is a rectangular area containing n × m cells. Two cells are marked with “2”, and another two with “3”. Some cells are occupied by obstacles. You should connect the two “2”s and also the two “3”s with non-intersecting lines. Lines can run only vertically or horizontally connecting centers of cells without obstacles.
Lines cannot run on a cell with an obstacle. Only one line can run on a cell at most once. Hence, a line cannot intersect with the other line, nor with itself. Under these constraints, the total length of the two lines should be minimized. The length of a line is defined as the number of cell borders it passes. In particular, a line connecting cells sharing their border has length 1.
Fig. 1(a) shows an example setting. Fig. 1(b) shows two lines satisfying the constraints above with minimum total length 18.
Figure 1: An example of setting and its solution
Input
The input consists of multiple datasets, each in the following format.
n m row1 … rown
n is the number of rows which satisfies 2 ≤ n ≤ 9. m is the number of columns which satisfies 2 ≤ m ≤ 9. Each rowi is a sequence of m digits separated by a space. The digits mean the following.
0:
Empty
1:
Occupied by an obstacle
2:
Marked with “2”
3:
Marked with “3”
The end of the input is indicated with a line containing two zeros separated by a space.
Output
For each dataset, one line containing the minimum total length of the two lines should be output. If there is no pair of lines satisfying the requirement, answer “0
” instead. No other characters should be contained in the output.
Sample Input
5 5 0 0 0 0 0 0 0 0 3 0 2 0 2 0 0 1 0 1 1 1 0 0 0 0 3 2 3 2 2 0 0 3 3 6 5 2 0 0 0 0 0 3 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 2 3 0 5 9 0 0 0 0 0 0 0 0 0 0 0 0 0 3 0 0 0 0 0 2 0 0 0 0 0 2 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 9 9 3 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 3 9 9 0 0 0 1 0 0 0 0 0 0 2 0 1 0 0 0 0 3 0 0 0 1 0 0 0 0 2 0 0 0 1 0 0 0 0 3 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 9 9 0 0 0 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 3 2 0 0
Sample Output
18 2 17 12 0 52 43
Source
#include<set> #include<queue> #include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int STATE = 59049+1000; const int Mod = 10007; #define For(i,n) for(int i=1;i<=n;i++) #define Rep(i,l,r) for(int i=l;i<=r;i++) #define Down(i,r,l) for(int i=r;i>=l;i--)struct statedp{int head[Mod],next[STATE],f[STATE],state[STATE];int size;void clear(){memset(head,-1,sizeof(head));size = 0;}void push(int st,int ans){int Key = st % Mod;for(int p = head[Key];p!=-1;p=next[p])if(st==state[p]){f[p] = min(f[p],ans);return;}state[size] = st;f[size] = ans;next[size] = head[Key];head[Key] = size++;} }dp[2];int n,m,maze[12][12],code[12];void init(){For(i,n)For(j,m)scanf("%d",&maze[i][j]); }void dpblock(int i,int j,int cur){int Lim = (j==m) ? (2) : (0);Rep(i,0,dp[cur].size-1)dp[cur^1].push(dp[cur].state[i] >> Lim , dp[cur].f[i]); }void shift(){Down(i,m,1) code[i] = code[i-1];code[0] = 0; }int encode(){int ret = 0;Rep(i,0,m) ret = ret << 2 | code[i];return ret; }void decode(int st){Down(i,m,0) code[i] = st & 3 , st >>= 2; }void dpblank(int i,int j,int cur){Rep(k,0,dp[cur].size-1){decode(dp[cur].state[k]);int Left = code[j-1] , Up = code[j];if(maze[i][j]>=2){if(Left&&Up) continue;int CODE = (maze[i][j]==2)?(1):2;if(Left||Up){if(Left+Up!=CODE) continue;code[j-1] = code[j] = 0;if(j==m) shift();dp[cur^1].push(encode(),dp[cur].f[k]);}else{if(i<n && maze[i+1][j] != 1){code[j-1] = CODE; code[j] = 0;if(j==m) shift();dp[cur^1].push(encode(),dp[cur].f[k]);}if(j<m && maze[i][j+1] != 1){code[j-1] = 0; code[j] = CODE;dp[cur^1].push(encode(),dp[cur].f[k]);}} continue;}if(Left && Up){if(Left!=Up) continue;code[j-1] = code[j] = 0;if(j==m) shift();dp[cur^1].push(encode(),dp[cur].f[k]+1);}else if(Left || Up){int CODE = Left | Up;if(i<n && maze[i+1][j]!=1){code[j-1] = CODE; code[j] = 0;if(j==m) shift();dp[cur^1].push(encode(),dp[cur].f[k]+1);}if(j<m && maze[i][j+1]!=1){code[j-1] = 0; code[j] = CODE;dp[cur^1].push(encode(),dp[cur].f[k]+1);}}else{if(!maze[i][j]){if(j==m) shift();dp[cur^1].push(encode(),dp[cur].f[k]);}if(i<n && j<m && maze[i+1][j]!=1 && maze[i][j+1]!=1){code[j-1] = code[j] = 1;dp[cur^1].push(encode(),dp[cur].f[k]+1);code[j-1] = code[j] = 2;dp[cur^1].push(encode(),dp[cur].f[k]+1);} }} }void DP(){int cur = 0;dp[0].clear();dp[0].push(0,0);For(i,n)For(j,m){dp[cur^1].clear();if(maze[i][j]==1) dpblock(i,j,cur);else dpblank(i,j,cur);cur^=1;}int ans = 2147483647;Rep(i,0,dp[cur].size-1) ans = min(ans,dp[cur].f[i]);if(ans==2147483647) ans = -2;printf("%d\n",ans+2); }int main(){while(scanf("%d%d",&n,&m),m+n){init();DP();}return 0; }
转载于:https://www.cnblogs.com/zjdx1998/p/3915598.html
POJ3133(插头dp)相关推荐
- [POJ3133]Manhattan Wiring 插头dp
[POJ3133]Manhattan Wiring 插头dp 原题POJ3133 题意:N*M有障碍矩阵,0可通过,1为障碍,两个2,两个3,求连接两个2和连接两个3的两条不相交路径长度和的最小值(1 ...
- [Poj3133]Manhattan Wiring (插头DP)
Description 题目大意:给你个N x M(1≤N, M≤9)的矩阵,0表示空地,1表示墙壁,2和3表示两对关键点.现在要求在两对关键点之间建立两条路径,其中两条路径不可相交或者自交(就是重复 ...
- bzoj1814 Ural 1519 Formula 1(插头dp模板题)
1814: Ural 1519 Formula 1 Time Limit: 1 Sec Memory Limit: 64 MB Submit: 924 Solved: 351 [Submit][S ...
- [入门向选讲] 插头DP:从零概念到入门 (例题:HDU1693 COGS1283 BZOJ2310 BZOJ2331)
转载请注明原文地址:http://www.cnblogs.com/LadyLex/p/7326874.html 最近搞了一下插头DP的基础知识--这真的是一种很锻炼人的题型-- 每一道题的状态都不一样 ...
- HDU4084 插头dp
题意:给定一个图,0是不能放的,然后现在有1X1和1X2方块,最后铺满该图,使得1X1使用次数在C到D之间,1X2次数随便,问有几种放法 思路:插头DP或轮廓线,多加一维DP讨论就可以 注意插头DP状 ...
- P3272 [SCOI2011]地板(插头DP)
[题面链接] https://www.luogu.org/problemnew/show/P3272 [题目描述] 有一个矩阵,有些点必须放,有些点不能放,用一些L型的图形放满,求方案数 [题解] ( ...
- POJ 3133 Manhattan Wiring (插头DP)
Manhattan Wiring Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 1110 Accepted: 634 D ...
- URAL1519 Formula 1 —— 插头DP
题目链接:https://vjudge.net/problem/URAL-1519 1519. Formula 1 Time limit: 1.0 second Memory limit: 64 MB ...
- [集训队作业2018]小Z的礼物(min-max容斥,插头dp)
传送门 这种求 "取到所有物品的期望时间" 的题一般都用 min−maxmin-maxmin−max容斥 解决: 设t(i,j)t(i,j)t(i,j)为取到格子(i,j)(i,j ...
最新文章
- Centos查找命令清单
- GCJ 2015-Qualification-B Infinite House of Pancakes 枚举,思路,误区 难度:3
- ubuntu16.4下用jexus部署asp.net core rtm
- 将Jersey与Spring整合
- java applet 访问文件_使用JavaApplet访问数据库
- JAVA minaio模型_分布式系统之Java IO模型
- flinkCdc的mysql配置及java测试代码
- java面向对象的理解_面向对象及其核心的概念:抽象、继承与多态、封装
- 使用Redis存取数据+数据库存取(spring+java)
- 推荐这5款Windows软件,一款比一款惊喜
- 批量将txt文件转为csv文件
- property follows cocoa naming convention for returning ‘owned‘ objects
- Spring源码剖析 循环注入
- 换个方式认识一下——微信公众号搜索公众号列表 API
- VSCode常用插件和字体设置
- rand和srand怎么用?
- 专家纵论智能机器社会的风险与解决方案
- java计算机毕业设计网上购物商城源代码+数据库+系统+lw文档
- it Ebook 免费
- 数学知识整理:不定积分