Hdu4374 monotonous queue optimized dp
I won't talk much about the meaning of the question. Let's talk about the ideas directly;
There are two ways to reach each layer's point (T step on the left side or T step on the right side ).
Dp [I] [j] = max (dp [I] [j], dp [I-1] [k] + sum [I] [j]-sum [I] [k-1]); // From the top k to the right dp [I] [j] = max (dp [I] [j], dp [I-1] [k] + sum [I] [k]-sum [I] [j-1]); // Comes to the left from the upper k point
Because the sum of each layer is fixed, only the maximum value of the condition dp [I-1] [k]-sum [I] [k-1] is required. This uses the monotonic queue for optimization. now
#include
#include
#include
using namespace std
;#define INF -0x3f3f3f3f
int sum
[20100
],num
[110
][20100
],id
[20100
],dp
[110
][20100
],map
[10010
];int max
(int a
,int b
){ return a
>b
?a
:b
;}int main(){ int n
,m
,i
,j
,x
,T
; while(~scanf
("%d%d%d%d"
,&n
,&m
,&x
,&T
)) { for(i
=1
;i
<=n
;i
++) for(j
=1
;j
<=m
;j
++) { scanf
("%d"
,&num
[i
][j
]); dp
[i
][j
]=INF
; } dp
[1
][x
]=num
[1
][x
]; for(i
=x
-1
;i
>=1
&&x
-i
<=T
;i
--) dp
[1
][i
]=dp
[1
][i
+1
]+num
[1
][i
]; for(i
=x
+1
;i
<=m
&&i
-x
<=T
;i
++) dp
[1
][i
]=dp
[1
][i
-1
]+num
[1
][i
]; int front
,top
; sum
[0
]=0
; for(i
=2
;i
<=n
;i
++) { for(j
=1
;j
<=m
;j
++) sum
[j
]=sum
[j
-1
]+num
[i
][j
]; front
=0
,top
=0
; for(j
=1
;j
<=m
;j
++) { int tt
=dp
[i
-1
][j
]-sum
[j
-1
]; while(front
<top
&&tt
>map
[top
]) top
--; id
[++top
]=j
; map
[top
]=tt
; while(j
-T
>id
[front
+1
]&&front
<top
) front
++; dp
[i
][j
]=max
(dp
[i
][j
],map
[front
+1
]+sum
[j
]); } front
=0
,top
=0
; sum
[m
+1
]=0
; for(j
=m
;j
>=1
;j
--) sum
[j
]=sum
[j
+1
]+num
[i
][j
]; for(j
=m
;j
>=1
;j
--) { int tt
=dp
[i
-1
][j
]-sum
[j
+1
]; while(front
<top
&&tt
>map
[top
]) top
--; id
[++top
]=j
; map
[top
]=tt
; while(front
<top
&&id
[front
+1
]>j
+T
) front
++; dp
[i
][j
]=max
(dp
[i
][j
],map
[front
+1
]+sum
[j
]); } } int Max
=INF
; for(i
=1
;i
<=m
;i
++) if(dp
[n
][i
]>Max
) Max
=dp
[n
][i
]; printf
("%d\n"
,Max
); } return 0
;}