• BZOJ1499: 瑰丽华尔兹(单调队列)


    pro: 给出一个n*m的地图,刚开始人在(x,y),每次给出一段区间(l,r,t),表示在时间[l,r]内,可以使人向4个方向(t)移动一格,或者不动。求最大可以移动多少格。

    sol: 考虑每一列(上下移)或者一行(左右移)的情况。以右移为例,我们可以很快列出dp方程:f[x][y][i]=max(f[x][y][i],f[x][j][i]+y-j)。这个dp方程我们可以用单调队列维护,所以复杂度就是nmk的。

    #include<bits/stdc++.h>
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    const int maxn=210;
    const int inf=1e9+7;
    int dp[maxn][maxn][2],ans;
    char c[maxn][maxn];
    int X[5]={0,-1,1,0,0},Y[5]={0,0,0,-1,1};
    int q[maxn][3],head,tail,N,M,now;
    int update(int x,int y,int tp,int tk)
    {
        int res=dp[q[tp][0]][q[tp][1]][(tk^1)&1]+now-q[tp][2];
        dp[x][y][tk&1]=max(dp[x][y][tk&1],res);
        return res;
    }
    int get(int tp,int tk)
    {
        int res=dp[q[tp][0]][q[tp][1]][(tk^1)&1]+now-q[tp][2];
        return res;
    }
    void work(int x,int y,int tK,int len,int opt)
    {
        head=1,tail=0; now=0;
        while(x>=1&&x<=N&&y>=1&&y<=M) {
            dp[x][y][tK&1]=dp[x][y][(tK^1)&1];
            if(c[x][y]=='x') head=1,tail=0;
            while(tail>=head&&now-q[head][2]>len) head++;
            while(tail>=head&&get(tail,tK)<dp[x][y][(tK^1)&1]) tail--;
            if(tail>=head)
                update(x,y,head,tK);
            ans=max(ans,dp[x][y][tK&1]);
            tail++; q[tail][0]=x; q[tail][1]=y; q[tail][2]=now++;
            x+=X[opt]; y+=Y[opt];
        }
    }
    int main()
    {
        int K,x,y,L,R,opt;
        scanf("%d%d%d%d%d",&N,&M,&x,&y,&K);
        rep(i,1,N) scanf("%s",c[i]+1);
        rep(i,1,N) rep(j,1,M) rep(k,0,K) dp[i][j][k]=-inf;
        dp[x][y][0]=0;
        rep(i,1,K){
            scanf("%d%d%d",&L,&R,&opt);
            if(opt==1) rep(j,1,M) work(N,j,i,R-L+1,opt);
            if(opt==2) rep(j,1,M) work(1,j,i,R-L+1,opt);
            if(opt==3) rep(j,1,N) work(j,M,i,R-L+1,opt);
            if(opt==4) rep(j,1,N) work(j,1,i,R-L+1,opt);
        }
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    20189222 《网络攻防技术》第十周作业
    20189222 《网络攻防技术》第九周作业
    20189222 《网络攻防技术》第八周作业
    20189222 《网络攻防技术》第七周作业
    20189209 《网络攻防技术》第六周作业
    20189209 《网络攻防技术》第五周作业
    20189209 《网络攻防技术》第四周作业
    20189209 《网络攻防技术》第三周作业
    20189209 《网络攻防技术》第二周作业
    快速排序+折半查找 c++
  • 原文地址:https://www.cnblogs.com/hua-dong/p/10988456.html
Copyright © 2020-2023  润新知