There are n vertices in a row, each of which has a weight value. Now you can start from any point and traverse other points. Each edge passing through two adjacent points reduces the edge weight by 1, calculate the maximum number of walking steps. Use two DP arrays to record the maximum number of walking steps left and right dp1 [I] [0] to indicate the maximum number of walking steps from I to left dp1 [I] [1] indicates the number of steps that can go to the left and return to the number of steps that the I can go to dp2. Similarly, you can retrieve the answer by traversing the page. View code
# Include <cstdio> # Include <Cstring> # Include <Algorithm> Using Namespace STD; Const Int Maxn = 100010 ; Long Long Num [maxn]; Long Long Dp1 [maxn] [ 2 ], Dp2 [maxn] [ 2 ]; Inline Long Long Max ( Long Long A, Long Long B ){ Return A> B?A: B;} inline Void Max ( Long Long & ANS, Long Long CMP ){ If (CMP> ans) ans = CMP ;} Int Main (){ Int N, I, J, K; scanf ( " % D " ,& N ); For (I = 2 ; I <= N; I ++) scanf ( " % LLD " ,& Num [I]); dp1 [ 1 ] [ 0 ] = 0 ; Dp1 [ 1 ] [ 1 ] = 0 ; For (I = 2 ; I <= N; I ++ ){ If (Num [I]> 1 ) Dp1 [I] [ 1 ] = Dp1 [I- 1 ] [ 1 ] + Num [I]/ 2 * 2 ; Else Dp1 [I] [ 1 ] = 0 ; If (Num [I] & 1 ) Dp1 [I] [ 0 ] = Dp1 [I- 1 ] [ 0 ] + Num [I]; Else Dp1 [I] [ 0 ] = Max (dp1 [I] [ 1 ], Dp1 [I- 1 ] [ 0 ] + Num [I]- 1 );} Dp2 [N] [ 0 ] = 0 ; Dp2 [N] [ 1 ] = 0 ; For (I = N- 1 ; I> = 1 ; I -- ){ If (Num [I + 1 ]> 1 ) Dp2 [I] [ 1 ] = Dp2 [I + 1 ] [ 1 ] + Num [I +1 ]/ 2 * 2 ; Else Dp2 [I] [ 1 ] = 0 ; If (Num [I + 1 ] & 1 ) Dp2 [I] [ 0 ] = Dp2 [I + 1 ] [ 0 ] + Num [I +1 ]; Else Dp2 [I] [ 0 ] = Max (dp2 [I] [ 1 ], Dp2 [I + 1 ] [ 0 ] + Num [I + 1 ]- 1 );} Long Long Ans = 0 ; For (I =1 ; I <= N; I ++ ) {Max (ANS, dp1 [I] [ 1 ] + Dp2 [I] [ 0 ]); Max (ANS, dp2 [I] [ 1 ] + Dp1 [I] [ 0 ]);} Printf ( " % I64d \ n " , ANS ); // I used % LLD for a long time. Return 0 ;}
Questions of the same type: poj2479