2019年9月1日砲兵位置

ポータル

記録状態番号と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 ; 
}

 

おすすめ

転載: www.cnblogs.com/qxds/p/11443399.html