题目链接

  我也不知道为什么脑子一抽就想了个堆优化……然后贼慢……

  因为上午听不懂wys的电音专场(快速傅立叶变换),然后就做了这么一道题。

  首先朴素DP很sb都能秒出。就是枚举时刻、位置(两维)然后转移。

  观察发现这是O(TNM)的,可以通过50%的数据。

  然后……(喂题目提示得太明显了吧)发现时间段只有200个,跟50%的T是一样的

  这简直就是明说:“快往O(KNM)上想!”

  然后我就不知道为啥想了个O(KNMlogn),qwq。

  枚举时刻改为枚举时间段,每个时间段枚举位置用堆优化(其实应该用单调队列)转移得出答案。

  虽然题目水+我的方法慢+我是sb+实现方法诡异+调了很久,1A还是很高兴的。

  (实现方法智障……可以当成锻炼代码能力嘛qwq)

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cctype>
#define maxn 205
using namespace std;
inline long long read(){
long long num=,f=;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-') f=-;
ch=getchar();
}
while(isdigit(ch)){
num=num*+ch-'';
ch=getchar();
}
return num*f;
} struct Node{
int dat,pos;
bool operator <(const Node a)const{
return dat>a.dat;
}
bool operator <=(const Node a)const{
return dat>=a.dat;
}
}; struct Heap{
Node heap[];int size;
Heap(){ size=;}
inline void push(Node x){
heap[++size]=x;
register int i=size,k;
while(i>){
k=i>>;
if(heap[k]<=heap[i]) return;
swap(heap[i],heap[k]);
i=k;
}
return;
}
inline bool empty(){ return !size; }
inline Node top(){ return heap[]; }
inline void clear(){size=;}
inline void pop(){
heap[]=heap[size--];
register int i=,k;
while((i<<)<=size){
k=i<<;
if(k<size&&heap[k|]<heap[k]) k|=;
if(heap[i]<=heap[k]) return;
swap(heap[i],heap[k]);
i=k;
}
}
}; Heap s[maxn]; int last,now=;
int f[maxn][maxn][];
char mp[maxn][maxn]; struct Line{
int from,to,dir;
bool operator <(const Line a)const{ return from<a.from; }
}q[maxn]; int main(){
int n=read(),m=read(),sx=read(),sy=read(),e=read();
for(int i=;i<=n;++i) scanf("%s",mp[i]+);
for(int i=;i<=e;++i) q[i]=(Line){read(),read(),read()};
sort(q+,q+e+);
memset(f,-/,sizeof(f));
f[sx][sy][last]=;
for(int i=;i<=e;++i){
int from=q[i].from,to=q[i].to,dir=q[i].dir;
if(dir<)
for(int j=;j<=m;++j){
s[j].clear();
if(dir==){
int cnt=;
for(int k=n;k;--k){
f[k][j][now]=-;
cnt++;
if(mp[k][j]=='x'){
s[j].clear();
continue;
}
if(s[j].empty()){
f[k][j][now]=f[k][j][last];
s[j].push((Node){f[k][j][last]-cnt,k});
continue;
}
Node ret=s[j].top();
while((!s[j].empty())&&ret.pos-k>to-from+){
s[j].pop();
ret=s[j].top();
}
if(s[j].empty()){
f[k][j][now]=f[k][j][last];
s[j].push((Node){f[k][j][last]-cnt,k});
continue;
}
//printf("%d %d %d %d\n",k,j,ret.pos,f[ret.pos][j][last]+ret.pos-k);
f[k][j][now]=max(f[k][j][last],f[ret.pos][j][last]+ret.pos-k);
s[j].push((Node){f[k][j][last]-cnt,k});
}
}
else{
int cnt=;
for(int k=;k<=n;++k){
f[k][j][now]=-;
cnt++;
if(mp[k][j]=='x'){
s[j].clear();
continue;
}
if(s[j].empty()){
f[k][j][now]=f[k][j][last];
s[j].push((Node){f[k][j][last]-cnt,k});
continue;
}
Node ret=s[j].top();
while((!s[j].empty())&&k-ret.pos>to-from+){
s[j].pop();
ret=s[j].top();
}
if(s[j].empty()){
f[k][j][now]=f[k][j][last];
s[j].push((Node){f[k][j][last]-cnt,k});
continue;
}
f[k][j][now]=max(f[k][j][last],f[ret.pos][j][last]+k-ret.pos);
s[j].push((Node){f[k][j][last]-cnt,k});
}
}
}
else
for(int j=;j<=n;++j){
s[j].clear();
if(dir==){
int cnt=;
for(int k=;k<=m;++k){
f[j][k][now]=-;
cnt++;
if(mp[j][k]=='x'){
s[j].clear();
continue;
}
if(s[j].empty()){
f[j][k][now]=f[j][k][last];
s[j].push((Node){f[j][k][last]-cnt,k});
continue;
}
Node ret=s[j].top();
while((!s[j].empty())&&k-ret.pos>to-from+){
s[j].pop();
ret=s[j].top();
}
if(s[j].empty()){
f[j][k][now]=f[j][k][last];
s[j].push((Node){f[j][k][last]-cnt,k});
continue;
}
//printf("%d %d %d\n",j,k,f[j][ret.pos][last]+k-ret.pos);
f[j][k][now]=max(f[j][k][last],f[j][ret.pos][last]+k-ret.pos);
s[j].push((Node){f[j][k][last]-cnt,k});
}
}
else{
int cnt=;
for(int k=m;k;--k){
f[j][k][now]=-;
cnt++;
if(mp[j][k]=='x'){
s[j].clear();
continue;
}
if(s[j].empty()){
f[j][k][now]=f[j][k][last];
s[j].push((Node){f[j][k][last]-cnt,k});
continue;
}
Node ret=s[j].top();
while((!s[j].empty())&&ret.pos-k>to-from+){
s[j].pop();
ret=s[j].top();
}
if(s[j].empty()){
f[j][k][now]=f[j][k][last];
s[j].push((Node){f[j][k][last]-cnt,k});
continue;
}
//printf("%d %d %d\n",j,k,f[j][ret.pos][last]+ret.pos-k);
f[j][k][now]=max(f[j][k][last],f[j][ret.pos][last]+ret.pos-k);
s[j].push((Node){f[j][k][last]-cnt,k});
}
}
}
swap(now,last);
}
int ans=;
for(int i=;i<=n;++i)
for(int j=;j<=m;++j) ans=max(ans,f[i][j][last]);
printf("%d\n",ans);
return ;
}

【Luogu】P2254瑰丽华尔兹(堆优化DP)的更多相关文章

  1. 【BZOJ1499】[NOI2005]瑰丽华尔兹 单调队列+DP

    [BZOJ1499][NOI2005]瑰丽华尔兹 Description 你跳过华尔兹吗?当音乐响起,当你随着旋律滑动舞步,是不是有一种漫步仙境的惬意?众所周知,跳华尔兹时,最重要的是有好的音乐.但是 ...

  2. 洛谷P1725 琪露诺 (单调队列/堆优化DP)

    显然的DP题..... 对于位置i,它由i-r~i-l的位置转移过来,容易得到方程 dp[i]=dp[i]+max(dp[i−r],...,dp[i−l]). 第一种:n2的暴力,只能拿部分分. 1 ...

  3. 征途堆积出友情的永恒「堆优化dp」

    直接写题解: 很简单的dp暴力转移式子:f[i]=MAX{f[j]+max(tax[j],sum[i]-sum[j])} 观察式子,只有一个变量sum[i]; 而其他都为定量; 则考虑维护 两个定量: ...

  4. 单调队列优化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 ...

  5. luogu P2254 [NOI2005]瑰丽华尔兹

    题目链接 luogu P2254 [NOI2005]瑰丽华尔兹 题解 为什么我我我不放放放bzoj的链接呢? 因为打的暴力啊,然后bzojT了呀QAQQQQQ(逃 然后luogu竟然过了呀呀呀 dp[ ...

  6. BZOJ 1499 [NOI2005] 瑰丽华尔兹 | 单调队列优化DP

    BZOJ 1499 瑰丽华尔兹 | 单调队列优化DP 题意 有一块\(n \times m\)的矩形地面,上面有一些障碍(用'#'表示),其余的是空地(用'.'表示).每时每刻,地面都会向某个方向倾斜 ...

  7. bzoj1499[NOI2005]瑰丽华尔兹 单调队列优化dp

    1499: [NOI2005]瑰丽华尔兹 Time Limit: 3 Sec  Memory Limit: 64 MBSubmit: 1802  Solved: 1097[Submit][Status ...

  8. 2018.09.10 bzoj1499: [NOI2005]瑰丽华尔兹(单调队列优化dp)

    传送门 单调队列优化dp好题. 这题其实很简单. 我们很容易想到一个O(T∗n∗m)" role="presentation" style="position: ...

  9. bzoj 1499 [NOI2005]瑰丽华尔兹——单调队列优化dp

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1499 简单的单调队列优化dp.(然而当时却WA得不行.今天总算填了坑) 注意滚动数组赋初值应 ...

随机推荐

  1. SAP CRM和C4C的客户主数据修改历史记录查询

    SAP CRM 随便修改一个字段,比如给Search Term维护值"webpack": Change History assignment block里显示出了这条修改记录: 根 ...

  2. 面试题-谈谈你对Java平台的理解

    平台无关性 GC 语言特性 面向对象 类库 异常处理 一次编译到处运行 JVM如何加载Class文件 Java反射 ClassLoader 种类 双亲委派机制 loadcalss和forName

  3. PopClip:你会热爱的文本穿梭机

    http://www.ifanr.com/234952 由于我是一名 Evernote 用户(不是印象笔记),最近发现它所提供的浏览器插件无论是 Web Cliper 还是 Clearly,反应速度都 ...

  4. LeetCode 53题 最大子序和 -- JavaScript

    解题思路分析: 该题是在一个整数数组中找到一个和最大的连续子数组,并返回和值.那么如何找到一个和最大的连续子数组呢?我们知道,这肯定需要遍历数组才行:好,那我们就开始遍历数组.首先,我们初始化最大和 ...

  5. iOS开发之MVVM在项目中的应用

    今天写这篇博客是想达到抛砖引玉的作用,想与大家交流一下思想,相互学习,博文中有不足之处还望大家批评指正.本篇博客的内容沿袭以往博客的风格,也是以干货为主,偶尔扯扯咸蛋(哈哈~不好好工作又开始发表博客啦 ...

  6. 深入理解 hashcode 和 hash 算法

    深入理解 hashcode 和 hash 算法 2017年12月30日 23:06:07 阅读数:5197 标签: hashhashmaphashcode二进制 更多 个人分类: jdk-源码  ht ...

  7. Fedora 28 系统基础配置以及常用软件安装方式

    实验说明: 很多人说Linux很难用,很难上手,其实不然,倘若不玩游戏,其实很多发行版Linux都可以成为主力系统,就比如本章要讲的 Fedora 28.本章会从镜像来源.系统安装.基础配置和常用软件 ...

  8. pandas时间数据的集成处理

    工作中遇到的一个问题: 统计各地区新能源汽车的充电时长 数据来源是北理新源的单日全球的运行数据. 这里仅统计北上广重庆四个地区的 数据处理的代码就省略了 需要整理好的是4个dataframe(数据已保 ...

  9. python3爬取豆瓣top250电影

    需求:爬取豆瓣电影top250的排名.电影名称.评分.评论人数和一句话影评 环境:python3.6.5 准备工作: 豆瓣电影top250(第1页)网址:https://movie.douban.co ...

  10. IDEA常用快捷键(不全)

    这里使用的是默认的idea快捷键,如果修改了keymap为其他,那么不适用. 1.格式化代码:Ctrl+Alt+L(可能与QQ的冲突,建议QQ只保留方便的截图,皮) 2.在当前行最后添加分号,或自动补 ...