博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HDU 3620 Ice-Skating
阅读量:6174 次
发布时间:2019-06-21

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

HDU_3620

    设f[i][x][y]表示第i个动作结束之后位置在(x,y)的最大步数,那么f[i][x][y]=std::max{f[i-1][x'][y']+distance((x,y),(x',y'))},然后根据第i个动作的行走方向来遍历数组并进行dp就可以了。但是由于每个动作可以向前行走的最大步数为200,如果再加一维循环表示这个动作走了多少步的话就会超时,不过可以用单调队列优化掉这一维,使得每次的决策都是O(1)的。

    此外,每次移动的步数可以是0,也就是不移动。

#include
#include
#include
#define MAXD 210int dx[] = {-1, 0, 1, 0}, dy[] = {
0, -1, 0, 1};char b[MAXD][MAXD];int N, M, K, sx, sy, q[MAXD], f[2][MAXD][MAXD];struct List{ int k, d;}list[MAXD];void init(){ int i; scanf("%d%d%d%d%d", &N, &M, &sx, &sy, &K), -- sx, -- sy; for(i = 0; i < N; i ++) scanf("%s", b[i]); for(i = 0; i < K; i ++) scanf("%d%d", &list[i].k, &list[i].d);}void solve(){ int i, j, k, cur = 0, flag, front, rear, ans = 0; for(i = 0; i < N; i ++) for(j = 0; j < M; j ++) f[0][i][j] = -1; f[0][sx][sy] = 0; for(k = 0; k < K; k ++) { cur ^= 1; if(list[k].d == 1) { for(j = 0; j < M; j ++) { front = rear = 0; for(i = N - 1; i >= 0; i --) { f[cur][i][j] = -1; if(b[i][j] == 'x') { front = rear; continue; } if(f[cur ^ 1][i][j] != -1) { while(front < rear && f[cur ^ 1][i][j] >= f[cur ^ 1][q[rear - 1]][j] + q[rear - 1] - i) -- rear; q[rear ++] = i; } while(front < rear && q[front] - i > list[k].k) ++ front; if(front < rear) f[cur][i][j] = f[cur ^ 1][q[front]][j] + q[front] - i; if(f[cur ^ 1][i][j] == -1) continue; } } } else if(list[k].d == 2) { for(i = 0; i < N; i ++) { front = rear = 0; for(j = M - 1; j >= 0; j --) { f[cur][i][j] = -1; if(b[i][j] == 'x') { front = rear; continue; } if(f[cur ^ 1][i][j] != -1) { while(front < rear && f[cur ^ 1][i][j]>= f[cur ^ 1][i][q[rear - 1]] + q[rear - 1] - j ) -- rear; q[rear ++] = j; } while(front < rear && q[front] - j > list[k].k) ++ front; if(front < rear) f[cur][i][j] = f[cur ^ 1][i][q[front]] + q[front] - j; } } } else if(list[k].d == 3) { for(j = 0; j < M; j ++) { front = rear = 0; for(i = 0; i < N; i ++) { f[cur][i][j] = -1; if(b[i][j] == 'x') { front = rear; continue; } if(f[cur ^ 1][i][j] != -1) { while(front < rear && f[cur ^ 1][i][j] >= f[cur ^ 1][q[rear - 1]][j] + i - q[rear - 1]) -- rear; q[rear ++] = i; } while(front < rear && i - q[front] > list[k].k) ++ front; if(front < rear) f[cur][i][j] = f[cur ^ 1][q[front]][j] + i - q[front]; } } } else { for(i = 0; i < N; i ++) { front = rear = 0; for(j = 0; j < M; j ++) { f[cur][i][j] = -1; if(b[i][j] == 'x') { front = rear; continue; } if(f[cur ^ 1][i][j] != -1) { while(front < rear && f[cur ^ 1][i][j] >= f[cur ^ 1][i][q[rear - 1]] + j - q[rear - 1]) -- rear; q[rear ++] = j; } while(front < rear && j - q[front] > list[k].k) ++ front; if(front < rear) f[cur][i][j] = f[cur ^ 1][i][q[front]] + j - q[front]; } } } } for(i = 0; i < N; i ++) for(j = 0; j < M; j ++) ans = std::max(ans, f[cur][i][j]); printf("%d\n", ans);}int main(){ int t; scanf("%d", &t); while(t --) { init(); solve(); } return 0;}

 

 

转载地址:http://ximba.baihongyu.com/

你可能感兴趣的文章
乔布斯走了,苹果会坠落吗?
查看>>
EFI分区不格盘,不重新分区,不丢数据安装32位win7方法
查看>>
java高级_01
查看>>
win8重装成win8.1后把hyperv的虚拟机导入
查看>>
服务器上线流程
查看>>
文件搜索命令:find
查看>>
linux命令汇总(mkdir、rmdir、touch、dirname、basename)
查看>>
mv或者cp带小括号文件名解析问题总结
查看>>
Java程序编译与执行
查看>>
获取单选按钮的值
查看>>
Elasticsearch学习笔记3: bulk批量处理
查看>>
EBS12.2.5 升级到EBS12.2.6的问题及跟踪处理
查看>>
网站访问流程
查看>>
java的日志工具log4j的配置方法
查看>>
jQuery on()方法
查看>>
步调一致才能得胜利
查看>>
mysql 锁机制
查看>>
add_header X-Frame-Options "SAMEORIGIN";NGINX
查看>>
java -- ==与equals的区别
查看>>
获取当前日期前x天日期
查看>>