Ural_1519
Plug DP debut is finally completed ^_^
For specific ideas, refer to Chen danqi's paper. I am only in the learning and imitation stages. I tried it in the smallest notation of Hu Hao's blog.CodeFor more information about plug DP, see hu Hao's blog: http://www.notonlysuccess.com/index.php/plug-dp-complete /.
# Include <stdio. h> # Include < String . H> # Define Maxd 15 # Define Hash 30007 # Define Size 1000010 Int N, m, maze [maxd] [maxd], code [maxd], CH [maxd], ex, ey; Char B [maxd]; Struct Hashmap { Int Size, head [hash], next [size]; Long Long F [size], State [size]; Void Init () {memset (Head, - 1 , Sizeof (Head); Size = 0 ;} Void Push ( Long Long St, Long Long Ans ){ Int I, H = sT % Hash; For (I = head [H]; I! =- 1 ; I = Next [I]) If (State [I] = St) {f [I] + = Ans; Return ;} State [size] = ST, F [size] = Ans; next [size] = Head [H]; head [H] = Size ++ ; }} HM [ 2 ]; Void Decode ( Int * Code, Int M, Long Long St ){ Int I; For (I = m; I> = 0 ; I -- ) {Code [I] = ST & 7 ; ST >>= 3 ;}} Long Long Encode ( Int * Code, Int M ){ Int I, CNT = 1 ; Long Long St = 0 ; Memset (CH, - 1 , Sizeof (CH); ch [ 0 ] = 0 ; For (I = 0 ; I <= m; I ++ ){ If (CH [Code [I] =- 1 ) CH [Code [I] = CNT ++ ; Code [I] = Ch [Code [I]; ST <= 3 ; ST | = Code [I];} Return St ;} Void Init (){ Int I, J, K; memset (maze, 0 , Sizeof (Maze); Ex = 0 ; For (I = 1 ; I <= N; I ++ ) {Scanf ( " % S " , B +1 ); For (J = 1 ; J <= m; j ++ ) If (B [J] = ' . ' ) Maze [ex = I] [ey = J] = 1 ;}} Void Shift ( Int * Code, Int M ){ Int I; For (I = m; I> 0 ; I -- ) Code [I] = Code [I- 1 ]; Code [ 0 ] = 0 ;} Void Dpblank ( Int I, Int J, Int Cur ){ Int K, T, left, up; For (K = 0 ; K <HM [cur]. size; k ++ ) {Decode (Code, M, HM [cur]. State [k]); left = Code [J- 1 ], Up = Code [J]; If (Left & UP) // Case 1 { If (Left =Up ){ If (I = ex & J = Ey) {code [J - 1 ] = Code [J] = 0 ; If (J = M) shift (Code, m); HM [cur ^ 1 ]. Push (encode (Code, m), HM [cur]. f [k]);} Else {Code [J - 1 ] = Code [J] = 0 ; For (T = 0 ; T <= m; t ++ ) If (Code [T] = Up) Code [T] = Left; If (J = M) shift (Code, m); HM [cur ^1 ]. Push (encode (Code, m), HM [cur]. f [k]);} Else If (Left) // Case 2 { If (Maze [I] [J + 1 ]) {Code [J - 1 ] = 0 , Code [J] = Left; HM [cur ^1 ]. Push (encode (Code, m), HM [cur]. f [k]);} If (Maze [I + 1 ] [J]) {code [J - 1 ] = Left, code [J] = 0 ; If (J = M) shift (Code, m); HM [cur ^ 1 ]. Push (encode (Code, m), HM [cur]. f [k]);} Else If (Up) // Case 3 { If (Maze [I] [J + 1 ]) {Code [J - 1 ] = 0 , Code [J] = Up; HM [cur ^ 1 ]. Push (encode (Code, m), HM [cur]. f [k]);} If (Maze [I + 1 ] [J]) {code [J - 1 ] = Up, code [J] = 0 ; If (J = M) shift (Code, m); HM [cur ^ 1 ]. Push (encode (Code, m), HM [cur]. f [k]);} Else // Case 4 { If (Maze [I] [J + 1 ] & Maze [I + 1 ] [J]) {code [J - 1 ] = Code [J] = 13 ; HM [cur ^ 1 ]. Push (encode (Code, m), HM [cur]. f [k]) ;}}} Void Dpblock ( Int I,Int J, Int Cur ){ Int K; For (K = 0 ; K <HM [cur]. size; k ++ ) {Decode (Code, M, HM [cur]. State [k]); Code [J - 1 ] = Code [J] = 0 ; If (J = M) shift (Code, m); HM [cur ^1 ]. Push (encode (Code, m), HM [cur]. f [k]);} Void Solve (){ Int I, j, cur = 0 ; Long Long Ans = 0 ; HM [cur]. INIT (); HM [cur]. Push ( 0 , 1 ); For (I =1 ; I <= N; I ++ ) For (J = 1 ; J <= m; j ++ ) {HM [cur ^ 1 ]. INIT (); If (Maze [I] [J]) dpblank (I, j, cur ); Else Dpblock (I, j, cur); cur ^ = 1 ;} For (I = 0 ; I <HM [cur]. size; I ++ ) Ans + = HM [cur]. f [I]; printf ( " % LLD \ n " , ANS );} Int Main (){ While (Scanf ( " % D " , & N, & M) = 2 ) {Init (); If (EX = 0 ) Printf ( " 0 \ n " ); Else Solve ();} Return 0 ;}