P2254 [NOI2005] 瑰丽华尔兹 题解
P2254 [NOI2005] 瑰丽华尔兹
搬运工
单调队列优化DP
还是先朴素,设
这里
#include<bits/stdc++.h> inline int read(){ char ch=getchar();int x=0,f=1; for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1; for(;ch>='0'&&ch<='9';ch=getchar())x=(x<<3)+(x<<1)+(ch^48); return x*f; } const int N=205; bool D[N][N]; int n,m,x,y,k,f[2][N][N],now,l[N],r[N],dir[N],q[N],head,tail; int main(){ // freopen("in.in","r",stdin);freopen("out.out","w",stdout); std::cout.tie(0); n=read(),m=read(),x=read(),y=read(),k=read(); memset(f,-0x3f,sizeof(f)); for(int i=1;i<=n;++i) for(int j=1;j<=m;++j){ char ch=getchar(); while(ch!='.'&&ch!='x')ch=getchar(); if(ch=='x')D[i][j]=true; } for(int i=1;i<=k;++i)l[i]=read(),r[i]=read(),dir[i]=read(); f[now][x][y]=0; for(int t=1;t<=k;++t,now^=1){ int len=r[t]-l[t]+1; if(dir[t]==1){ for(int j=1;j<=m;++j){ head=1,tail=0; for(int i=n;i;--i){ if(D[i][j]){head=1,tail=0;continue;} while(head<=tail&&f[now][i][j]-abs(i-n)>=f[now][q[tail]][j]-abs(q[tail]-n))tail--; q[++tail]=i; if(abs(q[head]-i)>len)head++; f[now^1][i][j]=f[now][q[head]][j]-abs(q[head]-n)+abs(i-n); } } } if(dir[t]==2){ for(int j=1;j<=m;++j){ head=1,tail=0; for(int i=1;i<=n;++i){ if(D[i][j]){head=1,tail=0;continue;} while(head<=tail&&f[now][i][j]-abs(i-1)>=f[now][q[tail]][j]-abs(q[tail]-1))tail--; q[++tail]=i; if(abs(q[head]-i)>len)head++; f[now^1][i][j]=f[now][q[head]][j]-abs(q[head]-1)+abs(i-1); } } } if(dir[t]==3){ for(int i=1;i<=n;++i){ head=1,tail=0; for(int j=m;j;--j){ if(D[i][j]){head=1,tail=0;continue;} while(head<=tail&&f[now][i][j]-abs(j-m)>=f[now][i][q[tail]]-abs(q[tail]-m))tail--; q[++tail]=j; if(abs(q[head]-j)>len)head++; f[now^1][i][j]=f[now][i][q[head]]-abs(q[head]-m)+abs(j-m); } } } if(dir[t]==4){ for(int i=1;i<=n;++i){ head=1,tail=0; for(int j=1;j<=m;++j){ if(D[i][j]){head=1,tail=0;continue;} while(head<=tail&&f[now][i][j]-abs(j-1)>=f[now][i][q[tail]]-abs(q[tail]-1))tail--; q[++tail]=j; if(abs(q[head]-j)>len)head++; f[now^1][i][j]=f[now][i][q[head]]-abs(q[head]-1)+abs(j-1); } } } } int ans=-1; for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)ans=std::max(ans,f[now][i][j]); std::cout<<ans<<'\n'; }
是一道挺好的单调队列优化DP
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!