【BZOJ1499】瑰丽华尔兹(动态规划)
【BZOJ1499】瑰丽华尔兹(动态规划)
题面
题解
先写部分分
设\(f[t][i][j]\)表示当前在\(t\)时刻,位置在\(i,j\)时走的最多的步数
这样子每一步要么停要么走
时间复杂度\(O(nmt)\)
得分\(40~70\)分
(据说这样能过???)
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define ll long long
#define RG register
#define MAX 210
inline int read()
{
RG int x=0,t=1;RG char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}
char g[MAX][MAX];
int ans,n,m,X,Y,K,L[MAX],R[MAX],D[MAX];
int d[5][2]={0,0,-1,0,1,0,0,-1,0,1};
int f[2][MAX][MAX],T[MAX*MAX];
int main()
{
n=read();m=read();X=read();Y=read();K=read();
for(int i=1;i<=n;++i)scanf("%s",g[i]+1);
for(int i=1;i<=K;++i)L[i]=read(),R[i]=read(),D[i]=read();
for(int i=1;i<=K;++i)
for(int j=L[i];j<=R[i];++j)T[j]=D[i];
memset(f,-1,sizeof(f));
f[0][X][Y]=0;
int nw=1,pw=0;
for(int tt=1;tt<=R[K];++tt,nw^=1,pw^=1)
{
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)f[nw][i][j]=-1;
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
{
if(f[pw][i][j]==-1)continue;
int xx=i+d[T[tt]][0],yy=j+d[T[tt]][1];
f[nw][i][j]=max(f[nw][i][j],f[pw][i][j]);
if(xx<1||yy<1||xx>n||yy>m)continue;
if(g[xx][yy]=='x')continue;
f[nw][xx][yy]=max(f[nw][xx][yy],f[pw][i][j]+1);
}
}
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
ans=max(ans,f[R[K]&1][i][j]);
printf("%d\n",ans);
return 0;
}
发现转移可以用单调队列优化
于是分四种情况进行讨论
用单调队列优化转移即可
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define ll long long
#define RG register
#define MAX 210
inline int read()
{
RG int x=0,t=1;RG char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}
char g[MAX][MAX];
int ans,n,m,X,Y,K,L[MAX],R[MAX],D[MAX];
int d[5][2]={0,0,-1,0,1,0,0,-1,0,1};
int f[2][MAX][MAX],T[MAX*MAX];
int Q[MAX],h,t;
int main()
{
n=read();m=read();X=read();Y=read();K=read();
for(int i=1;i<=n;++i)scanf("%s",g[i]+1);
for(int i=1;i<=K;++i)L[i]=read(),R[i]=read(),D[i]=read();
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)f[0][i][j]=-1e9;
f[0][X][Y]=0;
int nw=1,pw=0;
for(int tt=1;tt<=K;++tt,nw^=1,pw^=1)
{
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)f[nw][i][j]=f[pw][i][j];
if(D[tt]==1)
for(int j=1;j<=m;++j)
{
h=1;t=0;
for(int i=n;i;--i)
{
if(g[i][j]=='x'){h=1;t=0;continue;}
while(h<=t&&Q[h]-i>R[tt]-L[tt]+1)++h;
while(h<=t&&f[pw][Q[t]][j]+Q[t]<=f[pw][i][j]+i)--t;
Q[++t]=i;
if(h<=t)f[nw][i][j]=f[pw][Q[h]][j]+Q[h]-i;
}
}
else if(D[tt]==2)
for(int j=1;j<=m;++j)
{
h=1;t=0;
for(int i=1;i<=n;++i)
{
if(g[i][j]=='x'){h=1;t=0;continue;}
while(h<=t&&i-Q[h]>R[tt]-L[tt]+1)++h;
while(h<=t&&f[pw][Q[t]][j]-Q[t]<=f[pw][i][j]-i)--t;
Q[++t]=i;
if(h<=t)f[nw][i][j]=f[pw][Q[h]][j]+i-Q[h];
}
}
else if(D[tt]==3)
for(int i=1;i<=n;++i)
{
h=1;t=0;
for(int j=m;j;--j)
{
if(g[i][j]=='x'){h=1;t=0;continue;}
while(h<=t&&Q[h]-j>R[tt]-L[tt]+1)++h;
while(h<=t&&f[pw][i][Q[t]]+Q[t]<=f[pw][i][j]+j)--t;
Q[++t]=j;
if(h<=t)f[nw][i][j]=f[pw][i][Q[h]]+Q[h]-j;
}
}
else
for(int i=1;i<=n;++i)
{
h=1;t=0;
for(int j=1;j<=m;++j)
{
if(g[i][j]=='x'){h=1;t=0;continue;}
while(h<=t&&j-Q[h]>R[tt]-L[tt]+1)++h;
while(h<=t&&f[pw][i][Q[t]]-Q[t]<=f[pw][i][j]-j)--t;
Q[++t]=j;
if(h<=t)f[nw][i][j]=f[pw][i][Q[h]]+j-Q[h];
}
}
}
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
ans=max(ans,f[K&1][i][j]);
printf("%d\n",ans);
return 0;
}
【BZOJ1499】瑰丽华尔兹(动态规划)的更多相关文章
- Vijos1834 NOI2005 瑰丽华尔兹 动态规划 单调双端队列优化
设dp[t][x][y]表示处理完前t个时间段,钢琴停留在(x,y)处,最多可以走多少个格子 转移时只需逆着当前倾斜的方向统计len个格子(len为时间区间的长度,len=t-s+1),如果遇到障碍就 ...
- 洛谷2254 BZOJ1499 瑰丽华尔兹题解
洛谷链接 BZ链接 一个很容易想到的做法就是用f[i][j][t]表示t时刻在i,j处的可以滑动的最大值 f[i][j][t]=max(f[i][j][t-1],f[*i][*j][t-1]),这样大 ...
- 【BZOJ1499】【NOI2005】瑰丽华尔兹(动态规划)
[BZOJ1499]瑰丽华尔兹(动态规划) 题面 BZOJ 题解 先写部分分 设\(f[t][i][j]\)表示当前在\(t\)时刻,位置在\(i,j\)时走的最多的步数 这样子每一步要么停要么走 时 ...
- 【BZOJ1499】[NOI2005]瑰丽华尔兹 单调队列+DP
[BZOJ1499][NOI2005]瑰丽华尔兹 Description 你跳过华尔兹吗?当音乐响起,当你随着旋律滑动舞步,是不是有一种漫步仙境的惬意?众所周知,跳华尔兹时,最重要的是有好的音乐.但是 ...
- bzoj1499[NOI2005]瑰丽华尔兹 单调队列优化dp
1499: [NOI2005]瑰丽华尔兹 Time Limit: 3 Sec Memory Limit: 64 MBSubmit: 1802 Solved: 1097[Submit][Status ...
- [Bzoj1499][NOI2005]瑰丽华尔兹[简单DP]
1499: [NOI2005]瑰丽华尔兹 Time Limit: 3 Sec Memory Limit: 64 MBSubmit: 1714 Solved: 1042[Submit][Status ...
- DP+单调队列 codevs 1748 瑰丽华尔兹(还不是很懂具体的代码实现)
codevs 1748 瑰丽华尔兹 2005年NOI全国竞赛 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 大师 Master 题解 题目描述 Descripti ...
- NOI2005瑰丽华尔兹
1499: [NOI2005]瑰丽华尔兹 Time Limit: 3 Sec Memory Limit: 64 MBSubmit: 893 Solved: 508[Submit][Status] ...
- BZOJ 1499 [NOI2005] 瑰丽华尔兹 | 单调队列优化DP
BZOJ 1499 瑰丽华尔兹 | 单调队列优化DP 题意 有一块\(n \times m\)的矩形地面,上面有一些障碍(用'#'表示),其余的是空地(用'.'表示).每时每刻,地面都会向某个方向倾斜 ...
随机推荐
- 简单认识一下什么是vue-router
什么是vue-router? 用通俗一点的话来讲,其实就是一个url和组件之间的映射关系,当我们访问不同的url的时候在页面渲染不同的组件 vue-router怎么用? vue-router作为一个v ...
- Spring实战思维导图
简要包含Spring的Bean.AOP.事务.容器等方面:
- Java经典编程题50道之四十二
809*??=800*??+9*??+1,其中??代表的两位数,8*??的结果为两位数,9*??的结果为3位数.求??代表的两位数,以及809*??后的结果. public class Example ...
- scp的简单记忆方法
scp虽然只有把文见发送到远端和从远端copy文件俩功能,但是常常把俩功能的先写什么给计混了,所以我就用通俗的大白话给总结了下,十分容易记忆,这里给大家分享一下.scp 我们常用的两个功能: (1)把 ...
- 如何解决jQuery easyui中locale文件下easyui-lang-zh_CN中文乱码问题
1.在保存eclipse项目的目录下找到引入easyui-lang-zh_CN.js 2.用记事本打开该js文件,若打开后的中文正常,直接复制,粘贴到项目中的该js文件中,保存 3.若打开后中文出现乱 ...
- toString 方法在数组中的使用
对于一个一维数组,他在转换成字符串的时候应该调用Arrays.toString(); 对于一个多维数组,他在转换成字符串的时候应该调用Arrays.deepToString(); 实例: packag ...
- Vscode 插件
HTML Snippets Markdown All in One Markdown PDF Markdown Priview Enhanced Markdown TOC Open HTML in D ...
- the c programing language 学习过程3
ControlFlow 控制流 specify 指定 compound statement 复合语句 cryptic有隐含意义的 ambiguity歧义 robust稳健 disintegratio ...
- React——diff算法
react的diff算法基于两个假设: 1.不同类型的元素会产生不同的树 2.通过设置key,开发者能够提示那些子组件是稳定的 diff算法 当比较两个树时,react首先会比较两个根节点,接下来具体 ...
- 科学计算工具-Numpy初探
Numpy基础数据结构 Numpy数组是一个多维数组,称为ndarray.其由两部分组成: 实际的数据 描述这些数据的原数据 导入该库: import numpy as np 多维数组ndarray ...