記録状態番号とjの最後の行が最後から二番目のラインの状態の数が数kとされる前に明らかに私は圧力DP DP [I] [J] [K]を我慢したいと
それでは、DP [1]とDPを初期化してみましょう[2]
前記DP [1] [j]を[0] = BJ [1] [j]は、第0行がないように選択することができないので
以下DP [2] [J] [K] = BJ [1]〜[J] + BJ [2] [K] BJ配列と同じ意味
则当I> 2时DP [I] [J] [K] = MAX(DP [I] [J] [K]、DP [I-1] [K] [L] + BJ [I] [J] )
Lは、状態数の列挙の3行目である場合、BJ [i] [j]は、i番目の行のj番目の状態数を入れ
コード
書式#include <iostreamの> の#include <cstdioを> する#include <CStringの> に#define int型、長い長い 使って 名前空間はstdを、 int型 NUM [ 105 ] [(1 << 10)+ 1 ]、BJ [ 105 ] [(1 << 10)+ 1 ]、ANS、N、M、MAPP [ 105 ] [ 15 ]、DP [ 105 ] [ (1 << 10)+ 1 ] [(1 << 10)+ 1 ]。 ブール値のチェック(int型の R、INT X) { ため(int型 I = Mと、I> = 1 ; i-- ) { 場合(MAPP [R] [I] &&(X&!1))を返す 偽。 X >> = 1 。 } を返す 真。 } // 检查状态是否合法 INT getnum(INT R、INT X) { int型 RES = 0 。 一方、(X)RES + = X&1、X >> = 1 。 戻り BJ [R] [NUM [R] [ 0 ] =解像度; } // 初始化BJ数组 符号付きのmain() { scanf関数(" %のLLDの%のLLD "、&N、&M)。 char型のCH; 以下のために(int型私= 1 ; iが<= N; iが++ ) { ため(INT J = 1 ; J <= Mであり、j ++ ) { CIN >> CH。 もし(CH == ' P ')MAPP [I] [J] = 1 。 他の MAPP [i] [j]は= 0 ; } } INT MAXN =(1 - << M)1。; のための(INT I = 1 ; I <= N; I ++は) { ため(INT J = 0 ; J <= MAXN; J ++ ) { IF(チェック(I、J) !&&(&J(J << 1)!)&&(&J(J << 2 ))) { NUM [I] [ ++ NUM [I] [ 0 ] = J; // NUM [I] [J ]は、状態、NUM番号何のi行jを表す[I] [0]ラインは、法的地位の数を表し IF(I == 1)DP [I] [NUMを[I] [ 0 ] [ 0 ] = getnum(I、J)。 BJ [I] [NUM [I] [ 0 ] = getnum(i、j)は、 } } } のために(int型 I = 1 ; I <= NUM [ 2 ] [ 0 ]; iは++ ) { ための(int型 J = 1 ; J <= NUM [ 1 ] [ 0 ]; jは++ ) { int型 X = NUM [ 2 ] [i]は、Y = NUM [ 1 ] [J]。 もし(X&Y)続けます。 DP [ 2 ] [I] [J] = MAX(DP [ 2 ] [I] [J]、BJ [ 2 ] [I] + BJ [ 1] [J]); } } // 列挙初期化上下2列、DP [2] のための(INT I = 3 ; I <= N; I ++は) { ため(INT J = 1。 ; J <= NUM [I] [ 0 ]; J ++ ) { ため(INT K = 1 ; K <= NUM [I- 1 ] [ 0 ]; K ++ ) { ための(int型 L = 1。 ; L <= NUM [I- 2 ] [ 0 ]。 ++ L ) { INT X = NUM [I]、[J]、Y = NUM [I-1 ] [K]、Z = NUM [I- 2 ] [L]; IF((X&Y)||(Y&Z)||(X&Z))が続行; DP [I] [J] [K] = MAX(DP [I] [J] [K]、DP [I- 1 ] [K] [L] + BJ [I] [J]); } } } } // 列挙上り回線上のこのライン、 のための(INT I = 1 ; I <NUM = [N-] [ 0 ]; I ++は) { ため(INT J = 1。 ; J <= NUM [N- 1 ] [ 0 ]; J ++ ) { int型X = NUM [N-] [I]、Y = NUM [N- 1 ] [J]; IF(X&Y)を続行; ANS = MAX(ANS、DP [N-] [I]、[J]); } } // 列挙し、前の行であってもよい のprintf(" %のLLD " ; ANS) 戻り 0 ; }