[DP] hdu 4374 One hundred layer #单调队列优化

来源:互联网 发布:完全消耗系数矩阵例题 编辑:程序博客网 时间:2024/06/05 20:38
/**[DP] hdu 4374 One hundred layer #单调队列优化有一个的楼房,从第一层某个位置出发上楼,每次能爬上一层楼也可以在同一层左右移动,但是在每一层的移动距离不能超过某个值。。现在每个位置都有一个数值,求从第一层出发到最后一层经过的路径上最多能取到的最大价值。向右走时dp[i][j] = max(dp[i-1][k] + sum[i][j] - sum[i][k-1] )  k [j-t,j]         = max(dp[i-1][k] - sum[i][k-1]) + sum[i][j] 提出公共项,用单调队列维护最优值。向左同理WA了几次,1, dp[][] 要初始化为-INF; 2,区间向右走[s,e+t] 和[s-t,e]搞反了.*/#include <stdio.h>const int N = 101, M = 10001,INF = 1000000000;#define Max(a,b) ((a) > (b) ? (a) : (b))int sum[N][M],dp[N][M],a;int que[M],x,qs,qe,t,n,m,s,e,i,j;int main(){    while(scanf("%d%d%d%d",&n,&m,&x,&t) != EOF)    {        for(i = 1; i <= n; ++i)            for(j = 1; j <= m; ++j)            {                scanf("%d",&a);                sum[i][j] = sum[i][j-1] + a;                dp[i][j] = -INF;            }        for(i = x; i >= x - t && i > 0; --i)            dp[1][i] = sum[1][x] - sum[1][i-1];        for(i = x + 1; i <= x + t && i <= m; ++i)            dp[1][i] = sum[1][i] - sum[1][x-1];        s = e = x;        for(i = 2; i <= n; ++i)        {            s = s - t > 1 ? s - t: 1;            e = e + t < m ? e + t: m;            qs = qe = 0;            for(j = s; j <= e + t && j <= m; ++j)            {                while(qe > qs && dp[i-1][j] - sum[i][j-1] > dp[i-1][que[qe-1]] - sum[i][que[qe-1]-1])                    --qe;                que[qe++] = j;                dp[i][j] = dp[i-1][que[qs]] - sum[i][que[qs]-1]  + sum[i][j];                if(j - que[qs] >= t)                    ++qs;            }            qs = qe = 0;            for(j = e; j >= s - t && j > 0; --j)            {                while(qe > qs && dp[i-1][j] + sum[i][j] > dp[i-1][que[qe-1]] + sum[i][que[qe-1]])                    --qe;                que[qe++] = j;                dp[i][j] = Max(dp[i][j],dp[i-1][que[qs]] + sum[i][que[qs]] - sum[i][j-1]);                if(que[qs] - j >= t)                    ++qs;            }        }        a = dp[n][1];        for(i = 2; i <= m; ++i)            a = Max(a,dp[n][i]);        printf("%d\n",a);    }    return 0;}

原创粉丝点击