http://www.lydsy.com/JudgeOnline/problem.php?id=1499

  舞厅是一个N行M列的矩阵,矩阵中的某些方格上堆放了一些家具,其他的则是空地。钢琴可以在空地上滑动,但不能撞上家具或滑出舞厅,否则会损坏钢琴和家具,引来难缠的船长。每个时刻,钢琴都会随着船体倾斜的方向向相邻的方格滑动一格,相邻的方格可以是向东、向西、向南或向北的。而艾米丽可以选择施魔法或不施魔法:如果不施魔法,则钢琴会滑动;如果施魔法,则钢琴会原地不动。

  艾米丽是个天使,她知道每段时间的船体的倾斜情况。她想使钢琴在舞厅里滑行的路程尽量长,这样1900 会非常高兴,同时也有利于治疗托尼的晕船。但艾米丽还太小,不会算,所以希望你能帮助她。

……其实这是单调队列优化吧……

我们有一个显然的f[i][j][k]表示在i时间段内钢琴到(j,k)处时最大移动距离。

显然f可以很简单的转移,但是复杂度会爆炸。

但是又显然可以对每个点单调队列优化……

而且既然不是斜率优化,所以单调队列的维护也很简单,直接看代码吧。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long ll;
const int T=;
const int N=;
inline int read(){
int X=,w=;char ch=;
while(ch<''||ch>''){if(ch=='-')w=-;ch=getchar();}
while(ch>=''&&ch<='')X=(X<<)+(X<<)+ch-'',ch=getchar();
return X*w;
}
int f[T][N][N],qx[N],qy[N];
char s[N];
bool ok[N][N];
int dx[]={,-,,,};
int dy[]={,,,-,};
struct time{
int t,d;
}p[T];
int n,m;
void dp(int x,int y,int k){
int l=,r=;
while(x>=&&y>=&&x<=n&&y<=m){
while(l<r&&abs(x-qx[l])+abs(y-qy[l])>p[k].t)l++;
while(l<r&&!ok[x][y])r--;
while(l<r){
int t1=f[k-][qx[r-]][qy[r-]]+abs(x-qx[r-])+abs(y-qy[r-]);
int t2=f[k-][x][y];
if(t1<t2)r--;
else break;
}
if(ok[x][y]){
qx[r]=x,qy[r++]=y;
f[k][x][y]=f[k-][qx[l]][qy[l]]+abs(x-qx[l])+abs(y-qy[l]);
}
x+=dx[p[k].d];y+=dy[p[k].d];
}
}
int main(){
n=read(),m=read();
int x=read(),y=read(),t=read();
for(int i=;i<=n;i++){
scanf("%s",s+);
for(int j=;j<=m;j++)ok[i][j]=(s[j]=='.');
}
memset(f,-,sizeof(f));
f[][x][y]=;
for(int i=;i<=t;i++){
int t1=read(),t2=read();
p[i].t=t2-t1+;p[i].d=read();
}
for(int k=;k<=t;k++){
if(p[k].d==)
for(int j=;j<=m;j++)dp(n,j,k);
if(p[k].d==)
for(int j=;j<=m;j++)dp(,j,k);
if(p[k].d==)
for(int i=;i<=n;i++)dp(i,m,k);
if(p[k].d==)
for(int i=;i<=n;i++)dp(i,,k);
}
int ans=;
for(int i=;i<=n;i++){
for(int j=;j<=m;j++){
ans=max(ans,f[t][i][j]);
}
}
printf("%d\n",ans);
return ;
}

+++++++++++++++++++++++++++++++++++++++++++

+本文作者:luyouqi233。               +

+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

+++++++++++++++++++++++++++++++++++++++++++

最新文章

  1. web代理工具WebScarab
  2. poj 1847( floyd &amp;&amp; spfa )
  3. iOS开发UI篇—九宫格坐标计算
  4. HDFS中的checkpoint( 检查点 )的问题
  5. Oracle 调度程序(scheduler)摘自一位大神
  6. JavaScript 教程学习进度备忘(二)
  7. wp8 自定义相机+nokia滤镜+录制amr音频
  8. what is the virtual machine, when and why we need use it ?
  9. 常用linux命令和配置
  10. dubbo 负载均衡中策略决策
  11. Oracle10g安装中遇到的错误及解决办法
  12. android CheckBox与监听
  13. Saiku根据入参日期查询出对应的数据(二十)
  14. SHELL脚本学习-练习写一个脚本3
  15. ABAP 图形练习(GFW_PRES_SHOW and GRAPH_2D)
  16. 将html前端代码提取公因数(5)
  17. 【Java多线程通信】syncrhoized下wait()/notify()与ReentrantLock下condition的用法比较
  18. Project with Match in aggregate not working in mongodb
  19. 检查文件是否被修改或者被破坏工具 md5
  20. appium运行报错java.net.SocketException: socket write error

热门文章

  1. atomic是绝对的线程安全么?为什么?如果不是,那应该如何实现?
  2. Selenium 入门到精通系列:一
  3. wordlist 4
  4. python基本数据类型——元组
  5. NodeJs学习笔记01-你好Node
  6. New Year and Domino:二维前缀和
  7. Elasticsearch 排序插件的开发
  8. 从wait_type入手模拟SQL Server Lock
  9. 文件操作---基于python
  10. android BadgeView的使用(图片上的文字提醒)