bzoj 1499: [NOI2005]瑰丽华尔兹【dp+单调队列】
设f[a][i][j]为第a段时间结束时在(i,j)位置的最长滑行距离,转移很好想,就是分四个方向讨论,然后枚举这段时间的滑行长度取个max即可
但是这样是O(n^4)的,考虑优化
发现同一行或列,取max对应a-1中的是单调挪动的一个区间,所以用单调栈维护当前区间,每次移动的时候要把左端点已经大于最长滑行距离的出队,然后把新点放进去,然后直接更新答案,这样就省去了一个n的时间
注意如果遇到障碍的话,当前的f赋值-inf,然后把队列清空
#include<iostream>
#include<cstdio>
using namespace std;
const int N=205,dx[]={0,-1,1,0,0},dy[]={0,0,0,-1,1},inf=1e9;
int n,m,k,sx,sy,s[N],t[N],d[N],f[N][N][N],q[N],l,r,ans;
char c[N][N];
int main()
{
scanf("%d%d%d%d%d",&n,&m,&sx,&sy,&k);
for(int i=1;i<=n;i++)
scanf("%s",c[i]+1);
for(int i=1;i<=k;i++)
scanf("%d%d%d",&s[i],&t[i],&d[i]);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
f[0][i][j]=-inf;
f[0][sx][sy]=0;
for(int a=1;a<=k;a++)
{
if(d[a]==1)
{
for(int j=1;j<=m;j++)
{
l=1,r=0;
for(int i=n;i>=1;i--)
{
if(c[i][j]=='x')
{
l=1,r=0;
f[a][i][j]=-inf;
continue;
}
while(l<=r&&q[l]-i>t[a]-s[a]+1)
l++;
while(l<=r&&f[a-1][i][j]+i>f[a-1][q[r]][j]+q[r])
r--;
q[++r]=i;
f[a][i][j]=f[a-1][q[l]][j]+q[l]-i;
}
}
}
if(d[a]==2)
{
for(int j=1;j<=m;j++)
{
l=1,r=0;
for(int i=1;i<=n;i++)
{
if(c[i][j]=='x')
{
l=1,r=0;
f[a][i][j]=-inf;
continue;
}
while(l<=r&&i-q[l]>t[a]-s[a]+1)
l++;
while(l<=r&&f[a-1][i][j]-i>f[a-1][q[r]][j]-q[r])
r--;
q[++r]=i;
f[a][i][j]=f[a-1][q[l]][j]+i-q[l];
}
}
}
if(d[a]==3)
{
for(int i=1;i<=n;i++)
{
l=1,r=0;
for(int j=m;j>=1;j--)
{
if(c[i][j]=='x')
{
l=1,r=0;
f[a][i][j]=-inf;
continue;
}
while(l<=r&&q[l]-j>t[a]-s[a]+1)
l++;
while(l<=r&&f[a-1][i][j]+j>f[a-1][i][q[r]]+q[r])
r--;
q[++r]=j;//cerr<<i<<" "<<j<<" "<<q[l]<<" "<<f[a-1][i][j]+j<<" "<<f[a-1][i][q[l]]+q[l]<<endl;
f[a][i][j]=f[a-1][i][q[l]]+q[l]-j;
}
}
}
if(d[a]==4)
{
for(int i=1;i<=n;i++)
{
l=1,r=0;
for(int j=1;j<=m;j++)
{
if(c[i][j]=='x')
{
l=1,r=0;
f[a][i][j]=-inf;
continue;
}
while(l<=r&&j-q[l]>t[a]-s[a]+1)
l++;
while(l<=r&&f[a-1][i][j]-j>f[a-1][i][q[r]]-q[r])
r--;
q[++r]=j;//cerr<<i<<" "<<j<<" "<<q[l]<<endl;
f[a][i][j]=f[a-1][i][q[l]]+j-q[l];
}
}
}
// for(int i=1;i<=n;i++)
// {
// for(int j=1;j<=m;j++)
// cerr<<f[a][i][j]<<" ";
// cerr<<endl;
// }
// cerr<<endl;
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
ans=max(ans,f[k][i][j]);
printf("%d\n",ans);
return 0;
}
/*
10 10 5 8 5
..........
......xxxx
.....xxxxx
.....xxxxx
..........
xxxx......
..........
..........
..........
..x.......
1 5 3
6 7 1
8 11 2
12 15 3
16 17 2
*/
bzoj 1499: [NOI2005]瑰丽华尔兹【dp+单调队列】的更多相关文章
- BZOJ1499:[NOI2005]瑰丽华尔兹(DP,单调队列)
Description 你跳过华尔兹吗?当音乐响起,当你随着旋律滑动舞步,是不是有一种漫步仙境的惬意?众所周知,跳华尔兹时,最重要的是有好的音乐.但是很少有几个人知道,世界上最伟大的钢琴家一生都漂泊在 ...
- BZOJ 1499 [NOI2005] 瑰丽华尔兹 | 单调队列优化DP
BZOJ 1499 瑰丽华尔兹 | 单调队列优化DP 题意 有一块\(n \times m\)的矩形地面,上面有一些障碍(用'#'表示),其余的是空地(用'.'表示).每时每刻,地面都会向某个方向倾斜 ...
- bzoj 1499 [NOI2005]瑰丽华尔兹——单调队列优化dp
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1499 简单的单调队列优化dp.(然而当时却WA得不行.今天总算填了坑) 注意滚动数组赋初值应 ...
- BZOJ 1499 NOI2005 瑰丽华尔兹 单调队列
题目大意:给定一个m*n的地图,一些点有障碍物,钢琴初始在一个点,每一个时间段能够选择向给定的方向移动一段距离,求最长路径长 朴素DP的话,我们有T个时间段,每一个时间段有m*n个点,n个时间,一定会 ...
- BZOJ1499 [NOI2005]瑰丽华尔兹 【单调队列优化dp】
题目 你跳过华尔兹吗?当音乐响起,当你随着旋律滑动舞步,是不是有一种漫步仙境的惬意?众所周知,跳华尔兹时,最重要的是有好的音乐.但是很少有几个人知道,世界上最伟大的钢琴家一生都漂泊在大海上,他的名字叫 ...
- 2018.09.10 bzoj1499: [NOI2005]瑰丽华尔兹(单调队列优化dp)
传送门 单调队列优化dp好题. 这题其实很简单. 我们很容易想到一个O(T∗n∗m)" role="presentation" style="position: ...
- bzoj1499: [NOI2005]瑰丽华尔兹&&codevs1748 单调队列优化dp
这道题 网上题解还是很多很好的 强烈推荐黄学长 码风真的好看 神犇传送门 学习学习 算是道单调队列优化dp的裸题吧 #include<cstdio> #include<cstring ...
- ●BZOJ 1499 [NOI2005]瑰丽华尔兹
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=1499 题解: 单调队列优化DP 定义 dp[t][x][y] 表示第t个时间段之后,处在(x ...
- 洛谷P2254 [NOI2005]瑰丽华尔兹(单调队列)
传送门 题解 大概就是设$dp[i][x][y]$表示在第$i$个时间段,在$(x,y)$时的最大滑动距离 然后转移是$dp[i][x][y]=max(dp[i-1][x][y],dp[i][x'][ ...
随机推荐
- [Noip复习知识点][个人向]Zackzh
只是列列一些要复习的,努力复习吧,有种noip退役的赶脚. 一.模拟 (这你也不会?退役吧) 二.DP 1.基础dp 2.区间dp 3.状压dp 4.树形dp 6.概率(期望)dp 7.环形dp 8. ...
- QT程序--CS1.6文件整理及安装器
这是一个在高二的时候写的一个QT程序,当时对于QT也不算是特别熟悉吧,算是我第一个QT程序,当时由于CS1.6的文件安装的繁琐,又有一些服务器的管理的麻烦操作,对CS的服务器管理一直都很麻烦,当时高二 ...
- delphi 修改文件夹名和文件名
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Form ...
- 【转】nginx 和 php-fpm 通信使用unix socket还是TCP,及其配置
原文: http://blog.csdn.net/pcyph/article/details/46513521 -------------------------------------------- ...
- linux 查找目录下的文件内容并替换(批量)
2.sed和grep配合 命令:sed -i s/yyyy/xxxx/g `grep yyyy -rl --include="*.txt" ./` 作用:将当前目录(包括子目录)中 ...
- 【转】Linux下添加新硬盘,分区及挂载
原文:http://blog.chinaunix.net/uid-25829053-id-3067619.html ------------------------------------------ ...
- CodeForces - 344D Alternating Current (模拟题)
id=46667" style="color:blue; text-decoration:none">CodeForces - 344D id=46667" ...
- 单片机远程控制步进电机、LED灯和蜂鸣器
通过採用C#语言实现的上位机控制单片机的步进电机模块.LED灯和蜂鸣器模块,使步进电机进行正.反转和停止并控制转速:LED灯模块进行有选择的呼吸式表达:蜂鸣器模块的開始和终止. 上位机通过串口和自己定 ...
- 机器学习和深度学习笔记(Matlab语言实现)
不多说,直接上干货! 这里,对于想用matlab语言来做的朋友,强烈推荐 http://www.cnblogs.com/tornadomeet/
- Spring Task 定时任务
所谓定时任务.就是依据我们设定的时间定时运行任务,就像定时发邮件一样,设定时间到了.邮件就会自己主动发送. 在Spring大行其道的今天,Spring也提供了其定时任务功能,Spring Task.同 ...