1 条题解

  • 0
    @ 2025-11-21 15:18:46

    E49 单调队列优化DP 瑰丽华尔兹

    // 单调队列 O(KNM)
    #include<bits/stdc++.h>
    using namespace std;
    
    #define N 205
    int dx[5]={0,-1,1,0,0},dy[5]={0,0,0,-1,1};
    char mp[N][N];
    int n,m,sx,sy,K, ans,f[N][N];
    struct node{int f,pos;} q[N]; //最长距离f,位置pos
    
    //起点坐标x,y,行列长度L,时区长度tim,方向d
    void DP(int x,int y,int L,int tim,int d){
      for(int i=1,h=1,t=0; i<=L; i++){
        if(mp[x][y]=='x') h=1,t=0; //遇到障碍,清空队列
        else{
          while(h<=t && q[h].pos<i-tim) h++;
          while(h<=t && q[t].f+i-q[t].pos<=f[x][y]) t--;
          q[++t]=node{f[x][y],i};
          f[x][y]=q[h].f+i-q[h].pos;
          ans=max(ans,f[x][y]);
        }
        x+=dx[d],y+=dy[d];
      }
    }
    int main(){
      scanf("%d%d%d%d%d",&n,&m,&sx,&sy,&K);
      for(int i=1;i<=n;i++) scanf("%s",mp[i]+1);
      memset(f,-0x3f,sizeof(f)); f[sx][sy]=0;
      for(int k=1,s,t,d,tim;k<=K;k++){    //枚举k个时间区间
        scanf("%d%d%d",&s,&t,&d); tim=t-s+1;
        if(d==1) for(int i=1;i<=m;i++) DP(n,i,n,tim,d);//上
        if(d==2) for(int i=1;i<=m;i++) DP(1,i,n,tim,d);//下
        if(d==3) for(int i=1;i<=n;i++) DP(i,m,m,tim,d);//左
        if(d==4) for(int i=1;i<=n;i++) DP(i,1,m,tim,d);//右
      }
      printf("%d",ans);
    }
    
    
    • 1

    E49 单调队列优化DP [NOI2005] 瑰丽华尔兹

    信息

    ID
    2653
    时间
    1000ms
    内存
    128MiB
    难度
    10
    标签
    递交数
    2
    已通过
    1
    上传者