[解説] UVA1603は、正方形の広場デストロイヤーを弱体化させます

ヒューリスティック検索とビット操作、ハイブリッド話題の剪定です。

検索を学習するには、検索アルゴリズムは非常に重要です。これらの選手たちはよく遊んで非常に強力な検索です。(インストラクターリー別)

トピック分析

  • まず、\(n≤5の\) 及び辺の数である(2N(N + 1)≤60\)\しますビット演算は、小さなデータで最適化することができます。

  • ヒューリスティック検索、設計評価関数\(G(X-)\) これは、実際の価格よりも少ないが必要です。以下は、この方法です。

  • 各正方形のために、その辺のすべてを削除します。広場を知らない、この操作を繰り返します。操作の数が評価されています

  • しかし、これはこのタイトルを失っただけでは十分ではありません。また、それは、最適化する必要があります。

判決広場

  • 紙の上に、または直接法の導出の外観は、あなたが得ることができます:

  • 番号が配置されている場合、水平方向と一致する\(X_0 \)は

  • \(X_0 \)左下\(Lの\)一致され:$ X_I = X +(2I -1)N + I - 1、(0 <iがLを<)$。
  • 次に、左マージンの右端を決定する四角形の左端は、番号プラス側の長さです。
  • すべての正方形を前処理し、昇順インチ 背後にある理由は言うだろう
  • このようにDFS機能では、正方形を決定するためのコストを削減

ビットコンピューティングのスキル

  • ==符号なしとの長い長い==側面の数は広場を保存します。

  • 状態を向上させる側に四角があるかどうかを決意し、他の操作を完了するために==演算子| ==&==、==を使用します。具体的な実装があります

  • #define Mark(X,K) (X=X|((Ull)1<<((K)-1)))
    #define Del(X,K) (X&(~((Ull)1<<((K)-1))))
    #define Check(X,K) (X&(1<<((K)-1)))
  • == == == K X ==ビットの第1のマーク番号、およびタグを削除し、マークをチェック:3つのマクロ定義の役割があります。

以下の枝

  • 広場の前処理からは、完全な列挙の最小の選択は、そのエッジを削除します。
  • 広場の正面が不完全となっているので、あなたが苦労する必要はありません。そして、大量の注文に小さなので、探索木の枝が少なくなります。
  • 反復深化を使用します。

コードの一部を添付

  • 前処理四角:次のコード== X ==初期順序== Kは、正方形の辺の長さ==に戻ります。そして、保全の正方形の一辺の長さを開始します。

    Ull Get (int X , int K) {
      Ull Ans = 0 ;
      int Dlt = K * ((N << 1) + 1) ;
      for (int i = X ; i < X + K ; ++ i) Mark (Ans , i) , Mark (Ans , Dlt + i) ;
      for (int i = 1 ; i <= K; ++ i) 
          Mark (Ans , X + (2*i-1) * N + i - 1) , Mark (Ans ,X + (2*i-1) * N + i - 1 + K) ;
      return Ans ;
    }
  • 評価関数:1つの状態からビットを使用して全体の正方形の操作の除去:

    int G (Ull X) {
      int Ans = 0 ;
      for (int i = 1 ; i <= Cnt ; ++ i) {
          if( (S[i] & X) == S[i]) {
              ++ Ans ;
              X = X & (~S[i]) ;
          }
      }
      return Ans ;
    }
  • 検索:準備作業が行われているので、内部の検索機能は非常に簡単です。

    void DFS (Ull X , int Stp , int Des) {
    
      int Now = G(X) ;
      if (Now + Stp > Ans) return ;
      if (Now == 0 || Fl) {
          Fl = true ;
          return ;
      }
    
    while ((S[Des] & X) != S[Des]) ++ Des ;
    for (int i = F[Des] ; i < F[Des] + Len[Des] ; ++ i) {
          if (Check (X , F[Des]))DFS (Del (X , F[Des]) , Stp + 1 , Des + 1) ;
          if (Check (X , Len[Des] * ((N << 1) + 1) + i))
                DFS (Del ( X , Len[Des] * ((N << 1) + 1) + i) , Stp + 1 , Des + 1);
      }
    for (int i = 1 ; i <= Len[Des]; ++ i) {
      if (Check (X , F[Des] + (2*i-1) * N + i - 1))
              DFS( Del (X , F[Des] + (2*i-1) * N + i - 1) , Stp + 1 , Des + 1) ;
      if (Check (X , F[Des] + (2*i-1) * N + i - 1 + Len[Des])) 
              DFS (Del (X , F[Des] + (2*i-1) * N + i - 1 + Len[Des] ), Stp + 1 , Des + 1) ;
      }
    }

注空の配列

おすすめ

転載: www.cnblogs.com/bj2002/p/11367518.html