[NOI2005]瑰丽华尔兹
嘟嘟嘟
这题大家应该都做过,就是暴力dp+单调队列优化。
dp方程其实很好想,最初是这样的:dp[t][i][j]表示时刻\(t\)后,走到\((i, j)\)格子的最远路程,于是就有:
\]
但这是\(O(Tn ^ 2)\)的,不仅会TLE,还能MLE。
接着看题,发现给得\(K\)没用上。想一下发现\(K\)的特点是同一时间区间的移动方向是一样的,于是我们把第一维改成第\(k\)个时间区间,转移方程就变成了:
\]
\(len\)表示区间长度。
方程可能丑了点,但意思就是枚举这个点能在这个时间段内从哪儿转移过来,然后就是对应的dp值加上这两点之间的距离。
注意如果有的格子不能走,就不能从这里转移。
复杂度\(O(kn ^ 3)\)。
于是就有单调队列优化啦。
对于一个点,这一步能转移到他的实际上就是x或y方向上连续的一段dp值,于是我们把这些dp值放进单调队列里就行了。
这样优化到\(O(kn ^ 2)\),就过了。
需要注意的是,我们要用k - 1时刻更新k时刻的答案,因此先把dp[x][y]放入队列,再用队首更新dp值。这样就保证了放进去的dp值一定是上一个时刻的。
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<vector>
#include<stack>
#include<queue>
using namespace std;
#define enter puts("")
#define space putchar(' ')
#define Mem(a, x) memset(a, x, sizeof(a))
#define In inline
typedef long long ll;
typedef double db;
const int INF = 0x3f3f3f3f;
const db eps = 1e-8;
const int maxn = 205;
inline ll read()
{
ll ans = 0;
char ch = getchar(), last = ' ';
while(!isdigit(ch)) last = ch, ch = getchar();
while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
if(last == '-') ans = -ans;
return ans;
}
inline void write(ll x)
{
if(x < 0) x = -x, putchar('-');
if(x >= 10) write(x / 10);
putchar(x % 10 + '0');
}
int n, m, sx, sy, K;
char a[maxn][maxn];
struct Node
{
int L, R, dir;
}t[maxn];
int dp[maxn][maxn];
struct Que
{
int val, x, y;
}q[maxn];
int l = 1, r = 0;
const int dx[] = {0, -1, 1, 0, 0}, dy[] = {0, 0, 0, -1, 1};
In bool check(int x, int y) {return x && x <= n && y && y <= m;}
In int dis(int xa, int ya, int xb, int yb) {return abs(xa - xb) + abs(ya - yb);}
In void solve(int x, int y, int d, int len)
{
l = 1; r = 0;
while(check(x, y))
{
if(a[x][y] == 'x') l = 1, r = 0;
else
{
while(l <= r && q[r].val + dis(x, y, q[r].x, q[r].y) < dp[x][y]) --r;
q[++r] = (Que){dp[x][y], x, y};
while(l <= r && dis(x, y, q[l].x, q[l].y) > len) ++l;
dp[x][y] = q[l].val + dis(x, y, q[l].x, q[l].y);
}
x += dx[d]; y += dy[d];
}
}
int main()
{
n = read(); m = read(); sx = read(), sy = read(), K = read();
for(int i = 1; i <= n; ++i) scanf("%s", a[i] + 1);
for(int i = 1; i <= K; ++i) t[i].L = read(), t[i].R = read(), t[i].dir = read();
Mem(dp, -0x3f); dp[sx][sy] = 0;
for(int i = 1; i <= K; ++i)
{
if(t[i].dir == 1) for(int j = 1; j <= m; ++j) solve(n, j, t[i].dir, t[i].R - t[i].L + 1);
if(t[i].dir == 2) for(int j = 1; j <= m; ++j) solve(1, j, t[i].dir, t[i].R - t[i].L + 1);
if(t[i].dir == 3) for(int j = 1; j <= n; ++j) solve(j, m, t[i].dir, t[i].R - t[i].L + 1);
if(t[i].dir == 4) for(int j = 1; j <= n; ++j) solve(j, 1, t[i].dir, t[i].R - t[i].L + 1);
}
int ans = 0;
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= m; ++j) ans = max(ans, dp[i][j]);
write(ans), enter;
}
[NOI2005]瑰丽华尔兹的更多相关文章
- NOI2005瑰丽华尔兹
1499: [NOI2005]瑰丽华尔兹 Time Limit: 3 Sec Memory Limit: 64 MBSubmit: 893 Solved: 508[Submit][Status] ...
- bzoj1499[NOI2005]瑰丽华尔兹 单调队列优化dp
1499: [NOI2005]瑰丽华尔兹 Time Limit: 3 Sec Memory Limit: 64 MBSubmit: 1802 Solved: 1097[Submit][Status ...
- luogu P2254 [NOI2005]瑰丽华尔兹
题目链接 luogu P2254 [NOI2005]瑰丽华尔兹 题解 为什么我我我不放放放bzoj的链接呢? 因为打的暴力啊,然后bzojT了呀QAQQQQQ(逃 然后luogu竟然过了呀呀呀 dp[ ...
- 【BZOJ1499】[NOI2005]瑰丽华尔兹 单调队列+DP
[BZOJ1499][NOI2005]瑰丽华尔兹 Description 你跳过华尔兹吗?当音乐响起,当你随着旋律滑动舞步,是不是有一种漫步仙境的惬意?众所周知,跳华尔兹时,最重要的是有好的音乐.但是 ...
- [Bzoj1499][NOI2005]瑰丽华尔兹[简单DP]
1499: [NOI2005]瑰丽华尔兹 Time Limit: 3 Sec Memory Limit: 64 MBSubmit: 1714 Solved: 1042[Submit][Status ...
- 单调队列优化DP || [NOI2005]瑰丽华尔兹 || BZOJ 1499 || Luogu P2254
题外话:题目极好,做题体验极差 题面:[NOI2005]瑰丽华尔兹 题解: F[t][i][j]表示第t时刻钢琴位于(i,j)时的最大路程F[t][i][j]=max(F[t-1][i][j],F[t ...
- P2254 [NOI2005]瑰丽华尔兹
链接P2254 [NOI2005]瑰丽华尔兹 首先有个很朴素的\(dp\),设\(f_{i,j,k}\)表示\(k\)时刻地点\(i,j\)的最长长度. 然后这样不能优化,考虑利用一段连续时间是同一个 ...
- 题解-[NOI2005]瑰丽华尔兹
题解-[NOI2005]瑰丽华尔兹 [NOI2005]瑰丽华尔兹 \(n\times m\) 的矩阵.以 \((x,y)\) 为起点.一共 \(k\) 段时间,每段时间为 \([s_i,t_i](t_ ...
- BZOJ 1499 [NOI2005] 瑰丽华尔兹 | 单调队列优化DP
BZOJ 1499 瑰丽华尔兹 | 单调队列优化DP 题意 有一块\(n \times m\)的矩形地面,上面有一些障碍(用'#'表示),其余的是空地(用'.'表示).每时每刻,地面都会向某个方向倾斜 ...
- BZOJ1499:[NOI2005]瑰丽华尔兹(DP,单调队列)
Description 你跳过华尔兹吗?当音乐响起,当你随着旋律滑动舞步,是不是有一种漫步仙境的惬意?众所周知,跳华尔兹时,最重要的是有好的音乐.但是很少有几个人知道,世界上最伟大的钢琴家一生都漂泊在 ...
随机推荐
- FFmpeg编解码处理4-音频编码
本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10584948.html FFmpeg编解码处理系列笔记: [0]. FFmpeg时间戳详 ...
- Linux中inotify软件部署及参数事件演示
声明:博主使用的是CentOS6.9的系统 参考资料: https://github.com/rvoicilas/inotify-tools/wiki http://www.ibm.com/devel ...
- [css] css3 中的新特性加强记忆
css3被拆分成如下的小模块,选择器,盒模型,背景和边框,文字特效,2D/3D转换,动画,多列布局和用户界面 2D转换 使用transform:属性来为元素设置2D转换,兼容浏览器加前缀 –webki ...
- 通过IEnumerable接口遍历数据
使用IEnumerable接口遍历数据,这在项目中会经常的用到,这个类型呢主要是一个枚举器. 1.首先需要让该类型实现一个名字叫IEnumerable的接口,实现该接口的主要目的是为了让当前类型中增加 ...
- yum 安装 php5.6.36
PHP安装测试可以 rpm -Uvh http://ftp.iij.ad.jp/pub/linux/fedora/epel/6/i386/epel-release-6-8.noarch.rpm; rp ...
- 进程&线程&协程
进程 一.基本概念 进程是系统资源分配的最小单位, 程序隔离的边界系统由一个个进程(程序)组成.一般情况下,包括文本区域(text region).数据区域(data region)和堆栈(stac ...
- 2018-02-27 "Literate Programming"一书摘记之一
书到后才发现是Knuth的论文集, 第一篇就在网上: Computer programming as an art (1974). 其中"Taste and Style"(品味和风 ...
- Related concepts of testing
根据是否知道源代码测试可以分为黑盒和白盒. 黑盒:功能测试. 白盒:知道源代码,要写测试代码. 根据测试的粒度. 方法测试: 单元测试: 集成测试: 系统测试: 根据测试的暴力程度. 压力测试:谷歌工 ...
- 分享MYSQL中的各种高可用技术
分享MYSQL中的各种高可用技术 图片和资料来源于姜承尧老师(MYSQL技术内幕作者) mysql高可用各个技术的比较 数据库的可靠指的是数据可靠 数据库可用指的是数据库服务可用 可靠的是数据:例如工 ...
- [20180806]tune2fs调整保留块百分比.txt
[20180806]tune2fs调整保留块百分比.txt --//生产系统一台dg磁盘空间满了.我前一阵子已经将*convert参数修改,增加磁盘,但是这个分区里面的数据文件还可以增长,这样依旧存- ...