zoukankan      html  css  js  c++  java
  • bzoj 1499 [NOI2005]瑰丽华尔兹——单调队列优化dp

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1499

    简单的单调队列优化dp。(然而当时却WA得不行。今天总算填了坑)

    注意滚动数组赋初值应当继承上一次的该位置的值。还有转移的时候取个max。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int N=205,INF=16843010;//
    int n,m,x,y,T,l,r,d,dp[2][N][N],ans,q[N],h,t;
    char ch[N][N];
    int main()
    {
        scanf("%d%d%d%d%d ",&n,&m,&x,&y,&T);
        for(int i=1;i<=n;i++)cin>>(ch[i]+1);
        memset(dp,-2,sizeof dp);dp[0][x][y]=0;
        for(int s=1;s<=T;s++)
        {
            scanf("%d%d%d",&l,&r,&d);int u=(s&1),v=!u;int w=r-l+1;
            if(d==1)
            {
    //            q[0]=n;
                for(int j=1;j<=m;j++)
                {
                    for(int i=n;i;i--)
                    {
                        dp[u][i][j]=dp[v][i][j];//
                        if(ch[i][j]=='x')
                        {
    //                        h=0;t=0;q[0]=i-1;continue;
                            h=1;t=0;continue;
                        }
                        while(h<=t&&q[h]-i>w)h++;
                        while(h<=t&&dp[v][i][j]>=dp[v][q[t]][j]+(q[t]-i))t--;q[++t]=i;
                        if(dp[v][q[h]][j]>-INF||(q[h]==x&&j==y))dp[u][i][j]=max(dp[u][i][j],dp[v][q[h]][j]+(q[h]-i));//
    //                    printf("dp[%d][%d]=%d(dp[%d][%d]=%d i=%d q[%d]=%d)
    ",i,j,dp[u][i][j],q[h],j,dp[v][q[h]][j],i,h,q[h]);
                    }
                    h=1;t=0;//
                }
            }
            else if(d==2)
            {
    //            q[0]=1;
                for(int j=1;j<=m;j++)
                {
                    for(int i=1;i<=n;i++)
                    {
                        dp[u][i][j]=dp[v][i][j];//
                        if(ch[i][j]=='x')
                        {
    //                        h=0;t=0;q[0]=i+1;continue;
                            h=1;t=0;continue;
                        }
                        while(h<=t&&i-q[h]>w)h++;
                        while(h<=t&&dp[v][i][j]>=dp[v][q[t]][j]+(i-q[t]))t--;q[++t]=i;
                        if(dp[v][q[h]][j]>-INF||(q[h]==x&&j==y))dp[u][i][j]=max(dp[u][i][j],dp[v][q[h]][j]+(i-q[h]));//
    //                    printf("dp[%d][%d]=%d(dp[%d][%d]=%d i=%d q[%d]=%d)
    ",i,j,dp[u][i][j],q[h],j,dp[v][q[h]][j],i,h,q[h]);
                    }
                    h=1;t=0;//
                }
            }
            else if(d==3)
            {
    //            q[0]=m;
                for(int i=1;i<=n;i++)
                {
                    for(int j=m;j;j--)
                    {
                        dp[u][i][j]=dp[v][i][j];//
                        if(ch[i][j]=='x')
                        {
    //                        h=0;t=0;q[0]=j-1;continue;
                            h=1;t=0;continue;
                        }
                        while(h<=t&&q[h]-j>w)h++;
                        while(h<=t&&dp[v][i][j]>=dp[v][i][q[t]]+(q[t]-j))t--;q[++t]=j;
                        if(dp[v][i][q[h]]>-INF||(i==x&&q[h]==y))dp[u][i][j]=max(dp[u][i][j],dp[v][i][q[h]]+(q[h]-j));//
    //                    printf("dp[%d][%d]=%d(dp[%d][%d]=%d j=%d q[%d]=%d)
    ",i,j,dp[u][i][j],i,q[h],dp[v][i][q[h]],j,h,q[h]);
                    }
                    h=1;t=0;//
                }
            }
            else{
    //            q[0]=1;
                for(int i=1;i<=n;i++)
                {
                    for(int j=1;j<=m;j++)
                    {
                        dp[u][i][j]=dp[v][i][j];//
                        if(ch[i][j]=='x')
                        {
    //                        h=0;t=0;q[0]=j+1;continue;
                            h=1;t=0;continue;
                        }
                        while(h<=t&&j-q[h]>w)h++;
                        while(h<=t&&dp[v][i][j]>=dp[v][i][q[t]]+(j-q[t]))t--;q[++t]=j;
                        if(dp[v][i][q[h]]>-INF||(i==x&&q[h]==y))dp[u][i][j]=max(dp[u][i][j],dp[v][i][q[h]]+(j-q[h]));//
    //                    printf("dp[%d][%d]=%d(dp[%d][%d]=%d j=%d q[%d]=%d)
    ",i,j,dp[u][i][j],q[h],j,dp[v][q[h]][j],j,h,q[h]);
                    }
                    h=1;t=0;//
                }
            }
        }
        int u=(T&1);
        for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) ans=max(ans,dp[u][i][j]);
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    C#输出JS代码封装类Alart
    我的汇编学习之路(2)win8(64位)下安装debug
    .NET使用一般处理程序生成验证码
    ?运算符(null合并运算符)和三木运算符
    讲解:小菜鸟自制的.NET实体类生成器
    我的汇编学习之路(1)进制转换
    未来
    callee,caller区别
    string::size_type
    ubuntu 12.04 LTS u盘安装
  • 原文地址:https://www.cnblogs.com/Narh/p/9242132.html
Copyright © 2011-2022 走看看