您的位置:首页 > 其它

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

2012-08-17 12:24 661 查看
/**
[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
[M],dp
[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
[1];
for(i = 2; i <= m; ++i)
a = Max(a,dp
[i]);
printf("%d\n",a);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: