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'][ ...
随机推荐
- POJ 2240 【这题貌似可以直接FLOYD 屌丝用SPFA通过枚举找正权值环 顺便学了下map】
题意: 给了n种硬币的名称,给了m种硬币间的转换关系. 从任意兑换地点开始兑换,看是否能够通过兑换的方式增加金钱. 思路: 用SPFA不断对各个点进行松弛操作,寻找正权值的环.如果找到则输出Yes. ...
- Spring中基于AOP的@AspectJ
以下内容引用自http://wiki.jikexueyuan.com/project/spring/aop-with-spring-framenwork/aspectj-based-aop-with- ...
- ArcSDE数据库连接(直连、服务连)与GT_Geometry存
http://ziliao1.com/Article/Show/48126AB1A8F563D35E3D0345677C906B 众说周知,ArcSDE空间数据库引擎提供了两种连接数据库的方式.一是服 ...
- Office WORD如何简繁转换
选中要转换的文字,工具-语言,中文简繁转换.
- 程序运行中(BSS段、数据段、代码段、堆栈)
程序运行中(BSS段.数据段.代码段.堆栈) BSS段:(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域.BSS是英文Block Started by Symbol的简 ...
- c++中拷贝构造函数,浅拷贝和深拷贝的区别
在C++提供了一种特殊的构造函数,称为拷贝构造函数.拷贝构造函数具有一般构造函数的所有特性,其作用是使用一个已经存在的对象(由拷贝构造函数的参数指定的对象)去初始化一个新的同类对象,即完成本类对象的复 ...
- 1 TypeScript 简介与安装
简介: TypeScript 是一种由微软开发维护的自由和开源的编程语言,它是JavaScript的一个超集,支持可选的类型检查,扩展了JavaScript的语法,支持JavaScript的所有语法和 ...
- Linux服务基础命令
---恢复内容开始--- 1简介: Linux的网络功能相当强悍,一时之间我们无法了解所有的文阿罗命令,在配置服务器基础环境时,先了解下网络参数设定命令. ifconfig 查询,设置网卡和i ...
- Django模板语言(二)
1,装饰器:在不改变原函数的调用方式情况下为原函数增加一些功能(遵循开放封闭的原则) def outter(fn): def inner(*args, **kwargs): # 可以在执行函数前执行一 ...
- 6.游戏特别离不开脚本(3)-JS脚本操作java(直接解析JS公式,并非完整JS文件或者函数)
engine.put("usList", us); engine.put("obj", new JSModifiedJava()) ; 取个变量名就put进去 ...