最短の文字列

形状との組み合わせでAc_automaton圧力。

ルック質問はAc_automaton上のDPの説明であるが、実際に(もちろん、そこに組み込まれている完全なソリューションAc_automationが、その後、圧力DPの純粋なフォームを実行)文字列が後に選択されているかどうかを記録状の圧力のみを使用して、明白な転送プロセスはありません。

まずAc_automaton(トライ図)は、STAの追加の配列を維持するために、アレイはバイナリ配列で表され、「1」、「0」の文字列が発生したことを示す文字列が出現していることを示します。この情報は、オンラインソリューションで扱う問題のほとんどは、現在のノードの更新に失敗すると、情報が父親から引き継い転送、まだ交換することができますされていないことに注意することは、しかし、興味深い統計を挿入し、生成(構築)処理する必要があります。

失敗する最長の接尾辞のポインタによるメンテナンスの原則、文字列のサフィックスを想像用として浮上してきた、彼が出てくることができませんでしたか?次に登場した文字列(これを含む文字列、およびサブストリング相対)の文字列の父を考えると、それは現れない可能性があること。

どのようにしてANSを解決することです。まず考え、どのように我々は最低限の辞書的な問題を満たすことができます。

BFS、プッシュの外側の層の特性は、私たちが生きた状態を横断したときに、その後、彼は「層」として、最短である私たちは、この時点での長さであると言います。

A-から通常長い辞書> Zの列挙は保証することができます(この比率はミスでなければなりません)。

残りの問題のパスを記録することで、我々はBFS構造にIDを維持することができ、プッシュは次の状態への現在の状態を表し、次の状態の父の状態番号(それがその悩みを思わは)、私たちは前に、次のメソッドを使用します以下からの状態によって状態を記録した後、目的の状態を検索し、直接出力は、再帰することができます。

実際には、かなり悪い思考すぎ。

具体的な実装の詳細は、それを容易にするために、レコードの配列の中に、少し時間外(私は後で何とかLOGNのマップがあることを発見)した後、コードポインタキックを参照することができます。

 

#include <iostreamの> 
する#include <アルゴリズム> 
の#include <CStringの> 
する#include <cstdioを> 
する#include <ベクトル> 
の#include <キュー> 
の#include < 設定 > 
の#include <地図>
 使用して 名前空間STD。
構造体ノード{  
     int型のP、状態、ID。
}。
構造体プレ{  
     int型NUM、NEX。
}事前[ 60000000 ]。
INTのトライ[ 6000 ] [ 26 ]。
int型 N、TOT、根、CNT、LIS [ 6000 ]。
int型STA [ 6000 ]、失敗[ 6000 ]。
チャー S [ 60 ]。
ブール V [ 6000 ] [ 1 << 15 ]。
ボイドmclearが(){   
    TOT =ルート= 1 
} 
ボイドインサート(INT X){  
     int型今=ルートはL =のSTRLEN(S + 1 )。
    以下のためにint型 i = 1 ; iは= Lを<; iは++ ){  
         場合(!トライ[今] [S [i]は- ' A ' ])トライ[今] [S [I] - [ A '] = ++ TOT。トライを= [今] [S [I] - [ A ' ]。    
    } STA [今] | =(1 <<(X- 1 ))。
} 
ボイドは(){生成   
    キュー < INT > Qと、
    以下のためにint型 i = 0 ; iは< 26 ; iは++ 場合(トライ[ルート] [I]){   
            [トライ[ルート] [i]は]失敗 = ルートと、
            q.push(トライ[ルート] [I])。
        } 他のトライ[ルート] [I] = 根。
    しばらく(!q.empty()){  
         int型今= q.front()。
        q.pop(); 
        int型 iは= 0 ; iが< 26 ; iが++ 場合(トライ[今] [I]){   
                    [I] [トライ[今]失敗 = トライ[I] [今] [失敗]。    
                    q.push(トライ[今] [I])。
                    STA [トライ[今] [I]] | = STA [今]。
                } 他のトライ[今] [I] = トライを[I] [今] [失敗]。
    } 
    のためのint型 I = 1 ; I <= TOT; iが++ 
        STA [I] | =STA [i]は、[失敗]。
} 
無効印刷(int型x)は{  
     場合(!x)が復帰
    プリント(PRE [X] .nex)。
    printf(" %のC "、プレ[X] .nu​​m + ' A ' )。
} 
ボイドBFS(){   
    キュー <ノード> Q。int型のヘッド= 0、尾= 1 ; 
    q.push((ノード){ 10 })。
    V [ 1 ] [ 0 ] = 1 INTは =(終了1個の << N) - 1;
    一方、(!q.empty()){   
        ノードX = q.front()。
        q.pop(); 
        int型 = XP、STT = x.state、ID =今x.id。
        もし(両端== STT){   
                プリント(ID)。
                返します
        } 
        のためにint型 i = 0 ; iは< 26 ; I ++ ){  
             int型、Y = トライ[今] [I]。
            もし(V [Y] [STA [Y] | STT])続けます
            プレ[ ++ CNT] .nex = ID。
            プレ[CNT] .nu​​m = I。
            V [Y] [STA [Y] | STT] = 1 
            q.push((ノード){Y、STA [Y] | STT、CNT})。
        }     
    } 
} 
int型のmain(){   
    scanf関数(" %のD "、&N)
    mclearが(); 
    以下のためにint型私= 1 ; iが<= N; iが++ ){   
        scanf関数(" %sの"、S + 1 )。
        (i)を挿入します。
    } 
    を生成()。
    BFS(); 
    リターン 0 ; 
}
コードの表示

 

 

 

小さなOJを払って、メンテナンスなどのこの日のbzojの結果は、(、コードをテストビット醜いインデント、それを参照してください行い、メイン圧力のようななどBFSなぜ、圧力DPのような問題に対していくつかの解決策を見つけるためにインターネットを理解して理解していませんでしたこの問題はAc_automatonを学ぶために主にではあるが)。

おすすめ

転載: www.cnblogs.com/Yu-shi/p/11072109.html