[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;}