• hdu 4374 我的第一道单调队列优化的DP


      只贴代码:  

    View Code
    #include <algorithm>
    #include <iostream>
    #include <limits.h>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <queue>
    #include <stack>
    #include <cmath>
    #include <map>
    #include <set>
    
    using namespace std;
    
    const int maxn=105;
    const int maxm=10000+5;
    const int INF=0x3fffffff;
    
    int n,m,x,t;
    int val[maxn][maxm],sum[maxn][maxm],dp[maxn][maxm];
    int que[maxm],lq[maxm],rq[maxm];
    
    void init()
    {
        for(int i=1;i<=n+1;i++)
        {
            for(int j=1;j<=m;j++)
            {
                sum[i][j]=0;
                dp[i][j]=-INF;
                val[i][j]=0;
            }
        }
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                scanf("%d",&val[i][j]);
                sum[i][j]=sum[i][j-1]+val[i][j];
            }
        }
        int ss=0;
        for(int i=x;i>=x-t;i--)
        {
            ss+=val[1][i];
            dp[1][i]=ss;
            dp[2][i]=dp[1][i]+val[2][i];
        }
        ss=0;
        for(int i=x;i<=x+t;i++)
        {
            ss+=val[1][i];
            dp[1][i]=ss;
            dp[2][i]=dp[1][i]+val[2][i];
        }
    }
    
    void DP()
    {
        for(int i=3;i<=n+1;i++)
        {
            for(int j=1;j<=m;j++)
            {
                lq[j]=dp[i-1][j]-sum[i-1][j];
                rq[j]=dp[i-1][j]+sum[i-1][j-1];
            }
            int head,tail;
            head=1,tail=0;
            for(int j=1;j<=m;j++)
            {
                while(head<=tail&&lq[que[tail]]<=lq[j]) tail--;
                que[++tail]=j;
                while(head<=tail&&que[head]<j-t) head++;
                dp[i][j]=max(dp[i][j],lq[que[head]]+sum[i-1][j]+val[i][j]);
            }
            head=1,tail=0;
            for(int j=m;j>=1;j--)
            {
                while(head<=tail&&rq[que[tail]]<=rq[j]) tail--;
                que[++tail]=j;
                while(head<=tail&&que[head]>j+t) head++;
                dp[i][j]=max(dp[i][j],rq[que[head]]-sum[i-1][j-1]+val[i][j]);
            }
        }
        int ans=-INF;
        for(int j=1;j<=m;j++)
            ans=max(ans,dp[n+1][j]);
        printf("%d\n",ans);
    }
    
    int main()
    {
        while(~scanf("%d %d %d %d",&n,&m,&x,&t))
        {
            init();
            DP();
        }
        return 0;
    }

    不是一次过的,第一次提交之后跑了218ms wa掉了,感觉自己想的挺对的,后来找了下发现sum数组初始化的时候有点问题,后来又用for循环初始化了一下数组。结果就ac了,出乎我意料。感觉需要优化的dp,他的方程都不是特别难想?不清楚了,继续ac!五一节快乐!!

  • 相关阅读:
    推导式
    解构
    for 循环
    运算符
    while 循环
    流程控制语句
    索引和切片
    ASC转换BCD,ASC2BCD(转)
    CString和char互转,十六进制的BYTE转CString
    C++添加简单的日记记录
  • 原文地址:https://www.cnblogs.com/RainingDays/p/3053198.html
Copyright © 2020-2023  润新知