博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
POJ 1739 Tony's Tour
阅读量:5360 次
发布时间:2019-06-15

本文共 4192 字,大约阅读时间需要 13 分钟。

POJ_1739

即便看上去这个题目不像一个回路问题,但由于规定了起点和中间,实际上我们只要把起点和终点连一条线,这个题目就算变成一个求回路的问题了,只不过这个回路有些特殊。

具体处理的时候可以从下向上dp,然后把初始状态设置成在起点和终点的位置有两个相同的上插头即可。

#include
#include
#define HASH 30007#define MAXD 15#define SIZE 1000010int N, M, maze[MAXD][MAXD], code[MAXD], ch[MAXD], ex, ey;char b[MAXD];struct Hashmap{ int head[HASH], next[SIZE], state[SIZE], size; long long f[SIZE]; void init() { memset(head, -1, sizeof(head)); size = 0; } void push(int st, long long ans) { int i, h = st % HASH; for(i = head[h]; i != -1; i = next[i]) if(st == state[i]) { f[i] += ans; return ; } state[size] = st, f[size] = ans; next[size] = head[h]; head[h] = size ++; }}hm[2];void decode(int *code, int m, int st){ int i; for(i = m; i >= 0; i --) { code[i] = st & 7; st >>= 3; }}int encode(int *code, int m){ int i, cnt = 1, st = 0; memset(ch, -1, sizeof(ch)); ch[0] = 0; for(i = 0; i <= m; i ++) { if(ch[code[i]] == -1) ch[code[i]] = cnt ++; code[i] = ch[code[i]]; st <<= 3; st |= code[i]; } return st;}void init(){ int i, j, k; ex = 0; memset(maze, 0, sizeof(maze)); for(i = 1; i <= N; i ++) { scanf("%s", b + 1); for(j = M; j >= 1; j --) if(b[j] == '.') { maze[i][j] = 1; if(ex == 0) ex = i, ey = j; } }}void shift(int *code, int m){ int i; for(i = m; i > 0; i --) code[i] = code[i - 1]; code[0] = 0;}void dpblank(int i, int j, int cur){ int k, t, left, down; for(k = 0; k < hm[cur].size; k ++) { decode(code, M, hm[cur].state[k]); left = code[j - 1], down = code[j]; if(left && down) { if(left == down) { if(i == ex && j == ey) { code[j - 1] = code[j] = 0; if(j == M) shift(code, M); hm[cur ^ 1].push(encode(code, M), hm[cur].f[k]); } } else { code[j - 1] = code[j] = 0; for(t = 0; t <= M; t ++) if(code[t] == down) code[t] = left; if(j == M) shift(code, M); hm[cur ^ 1].push(encode(code, M), hm[cur].f[k]); } } else if(left || down) { if(maze[i][j + 1]) { code[j - 1] = 0, code[j] = left + down; hm[cur ^ 1].push(encode(code, M), hm[cur].f[k]); } if(maze[i - 1][j]) { code[j - 1] = left + down, code[j] = 0; if(j == M) shift(code, M); hm[cur ^ 1].push(encode(code, M), hm[cur].f[k]); } } else { if(maze[i - 1][j] && maze[i][j + 1]) { code[j - 1] = code[j] = 13; hm[cur ^ 1].push(encode(code, M), hm[cur].f[k]); } } }}void dpblock(int i, int j, int cur){ int k; for(k = 0; k < hm[cur].size; k ++) { decode(code, M, hm[cur].state[k]); code[j - 1] = code[j] = 0; if(j == M) shift(code, M); hm[cur ^ 1].push(encode(code, M), hm[cur].f[k]); }}void solve(){ int i, j, cur = 0; long long ans = 0; memset(code, 0, sizeof(code)); code[1] = code[M] = 1; hm[cur].init(); hm[cur].push(encode(code, M), 1); for(i = N; i >= 1; i --) for(j = 1; j <= M; j ++) { hm[cur ^ 1].init(); if(maze[i][j]) dpblank(i, j, cur); else dpblock(i, j, cur); cur ^= 1; } for(i = 0; i < hm[cur].size; i ++) ans += hm[cur].f[i]; printf("%lld\n", ans);}int main(){ for(;;) { scanf("%d%d", &N, &M); if(!N && !M) break; init(); solve(); } return 0;}

转载于:https://www.cnblogs.com/staginner/archive/2012/04/19/2457877.html

你可能感兴趣的文章
linux下mysql开启远程访问权限及防火墙开放3306端口
查看>>
开发项目中遇到的问题集锦随时更新
查看>>
C语言中的未初始化变量的值
查看>>
二叉查找树(查找最大值、最小值、给定值、删除给定值的实现)
查看>>
HDU 6397(容斥原理)
查看>>
Spring中配置文件中引用外部文件
查看>>
java中有关初始化的问题
查看>>
【转】除锈的机器是啥原理?
查看>>
基本数据类型和操作
查看>>
Android开发所有视频教程汇总
查看>>
Java Hashtable遍历与方法使用
查看>>
两个优美的等宽字体(支持中文等)
查看>>
mysql5.7.19安装报错 无法定位程序输入点
查看>>
Hello World!
查看>>
使用SOAPUI测试WEBAPI接口
查看>>
method=post和三个按钮
查看>>
POJ 2296 Map Labeler (二分+2-sat,4级)
查看>>
CF-51C - Three Base Stations(二分或枚举优化)
查看>>
数字组合问题:Combination,CombinationSum,CombinationSum2,CombinationSum3
查看>>
367. Valid Perfect Square
查看>>