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

本文分享了一个动态规划问题的解决过程,通过优化初始化过程,成功将运行时间从218ms降至可接受范围,并最终通过了评测。文章详细展示了代码实现,包括使用多种数据结构和算法技巧,如滑动窗口和单调队列。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  只贴代码:  

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!五一节快乐!!

转载于:https://www.cnblogs.com/RainingDays/archive/2013/05/01/3053198.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值