题目链接

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

  因为上午听不懂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. BZOJ 1137: [POI2009]Wsp 岛屿 半平面交

    1137: [POI2009]Wsp 岛屿 Time Limit: 10 Sec  Memory Limit: 162 MBSec  Special JudgeSubmit: 165  Solved: ...

  2. ios常见错误之 Failed to instantiate the default view controller for UIMainStoryboardFile 'Main' - perhaps the designated entry point is not set?

    Failed to instantiate the default view controller for UIMainStoryboardFile 'Main' - perhaps the desi ...

  3. C++内存溢出和内存泄漏?

    1.内存溢出 内存溢出是指程序在申请内存时没有足够的内存空间供其使用.原因可能如下: (1)内存中加载的数据过于庞大: (2)代码中存在死循环: (3)递归调用太深,导致堆栈溢出等: (4)内存泄漏最 ...

  4. c++文件偏移

    #include <iostream> #include <fstream> #include <cassert> using namespace std; int ...

  5. javaweb基础(12)_session详解

    一.Session简单介绍 在WEB开发中,服务器可以为每个用户浏览器创建一个会话对象(session对象),注意:一个浏览器独占一个session对象(默认情况下).因此,在需要保存用户数据时,服务 ...

  6. javaweb基础(11)_cookie的会话管理

    一.会话的概念 会话可简单理解为:用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话. 有状态会话:一个同学来过教室,下次再来教室,我们会知道这个同学曾 ...

  7. 解决Error"基础连接已经关闭: 未能为SSL/TLS 安全通道建立信任关系

    今天写程序的时候调用到一个第三方的DLL文件,本机调试一切都正常,但是程序不是到服务器以后一直提示一个BUG:"基础连接已经关闭: 未能为SSL/TLS 安全通道建立信任关系".  ...

  8. linux交换分区调整

      SWAP就是LINUX下的虚拟内存分区,它的作用是在物理内存使用完之后,将磁盘空间(也就是SWAP分区)虚拟成内存来使用.它和Windows系统的交换文件作用类似,但是它是一段连续的磁盘空间,并且 ...

  9. Noip 训练指南

    目录 Noip 训练指南 图论 数据结构 位运算 期望 题解 Noip 训练指南 目前完成 \(4 / 72\) 图论 [ ] 跳楼机 [ ] 墨墨的等式 [ ] 最优贸易 [ ] 泥泞的道路 [ ] ...

  10. 【线段树 泰勒展开】Codechef April Challenge 2018 Chef at the Food Fair

    第一次写泰勒展开:本地和CC差距好大 题目大意 大厨住的城市里办了一场美食节.一条街上开设了$N$个摊位,编号为$1∼N$.这天开始时,第$i$个摊位的食物会导致食物中毒的概率是$P_i$.在这一天中 ...