E. Nanosoft(前処理、三次元DP)

タイトル:ポータル

質問の意味: 

   ロゴは一つの大きな正方形にNanosoft 4つの同一の正方形のサイズを定義しています。左上隅は右上隅が緑色、赤色であり、左下は、右下隅が青色、黄色です。

   これらは、例えば以下の通りです。

   

   これらはそうではありません

 

 

 

 

 

 

    次の4つの大文字は、赤、緑、黄色、青を表し、* 4大文字「R」、「G」、「Y」、「B」構成の行列をM行列をNを与えます。

      時間クエリQ、各問い合わせ、二つの入力座標(X1、Y1)、(X2、Y2)代表(X1、Y1)行列の左上隅の座標(X2、Y2)があると、マトリックスの右下隅の座標でありますマトリックスは、Nanosoft最大サブマトリクスであるロゴとして使用することができます。

 

ソリューション: 

  まず、事前に[I] [J] [COL]代表的なマトリックス(1、1)を定義する、(i、j)はどのように多くのグリッド色COL、即ち接頭二次元では、これは非常に単純なプリアウトすることができ。 

  明らかに、ロゴは、正方形である必要がありますNanosoftとして使用することができ、かつ辺の長さは偶数でなければなりません。

  次に[I] [J] [K](i、j)はk個の正方形の右下隅でのように、子供のような正方形の最大辺の長さがNanosoftは、また、それがロゴであることができる(DP定義I - K + 1、J - K + 1)左上、(i、j)は正方形の辺の長さは、ロゴNanosoftの副最大値として使用することができ、正方形の右下隅です。

  伝達式は、DP [I] [J] [K] = MAX({DP [I] [J] [K]、DP [I] [J] [K - 1]、DP [I - 1] [J ] [K - 1]、DP [I]、[J - 1] [K - 1]、DP [I - 1] [J - 1] [K - 1]})。

  我々はまたにO(1)時間で決定された(i、j)は、ロゴNanosoft全体かK正方形エネルギーの辺の長さ右下隅の座標であり、缶、次にDP [I] [J] [K ] Kです。

  各クエリに対して、我々は正方形の最大辺の長さが最小であることを知っている(X2 - X1 + 1、Y2 - Y1 + 1)。

  その後、我々は、この広場を列挙することができます。各クエリまで(N、M)倍であり、その最大列挙され、n個の複雑さは* qはタイムアウトではないだろう。

#include <ビット/ STDC ++ H>
 の#define LL長い長
 の#define MEM(i、j)はmemsetの(I、J、はsizeof(I))
 の#define(INTのための担当者(I、J、K)は、iがjを=。 I <= K; I ++)
 の#define(int型のためのDEP(i、j、k)はiのkは=; I> = J; i--)
 の#define PB一back
 の#define作るmake_pair
 の#define INF INT_MAX
 の#define INF LLONG_MAX
 #定義 PIのACOSを(-1)
 使用して 名前空間はstdを、

CONST  INT N = 510 

チャー[N] [N]。
チャー S [] = " RGYB " 整数N、M、Q。
INT事前[N] [N] [ 4 ]; /// 青黄2、グリーン1、赤色用の三次元、0、3 
INT DP [N] [N] [N]; 

int型チェック(INTルクス、INT Luy、INT RDX、INT RDY、INT COL){
     リターンプレ[RDX] [RDY] [COL] -プレ[RDX] [Luy - 1 ] [COL] -プレ[ルクス- 1 ] [RDY] [ COL] +プレ[ラックス- 1 ] [Luy - 1 ] [COL]; 
} 

無効(INIT)を{ 
    REP(K、03)REP(I、1、N-)REP(J、1 、m)と
        [I] [J] [k]はのために - [I = 1 [I]に] [J] [K] +を[J - 1 ] [K] - - [iを1 [J - ] 1 ] [A ] +([I] [J] == P [K])。
    担当者(I、1、n)の担当者(J、1 、M){
         ためINT A = 1 ; K <=分(i、j)は、K ++ ){
             場合(kは%2 == 0 ){
                 int型 LEN = / 2 ;
                もし(チェック(I -のみ+ 1、J -のみ+ 1、I、J、3)== *のみとして
                 &&検査(および-として+ 1、J - K + 1、I、J -のみ、2)==のみ* のみ
                  &&チェック(I - K + 1、J -のみ+ 1、および-のみ、J、1)= * =のみだけ
                  &&チェック(I - K + 1、J - K + 1、および-のみJ -のみ、0)== *のみのみ)
                    DP [I] [J] [K] = 
            } 
            Dpを[I] [J] [K] = MAX({DP [I] [J] [K]、DP [I] [J] [K - 1 ]、DP [I - 1 ] [J] [K - 1 1]、DP [I]、[J - ] [K - 1 ]、DP [I - 1 ] [J - 1 ] [K - 1 ]})。
        } 
    } 
} 

int型のmain(){ 

    scanf関数(" %D%D%D "、&​​N、&M&Q)。
    担当者(I、1、N)のscanf(" %S "、[I] + 1 )。
    初期化(); 
    一方、(q-- ){
         int型X1、X2、Y1、Y2、
        scanf関数(" %D%D%D%D "、&​​X1、Y1、X2&&&Y2)。
        int型LEN =分(X2 - X1 +  1、Y2 - Y1 + 1 )。
        int型 ANS = 0 ;
        もし(X2 - X1> Y2 - Y1){
             int型 DIS =(X2 - X1) - (Y2 - Y1)。
            担当者(I、0、DIS)ANS = MAX(ANS、DP [X2 - I] [Y2] [LEN])。
        } 
        {
             INT DIS =(Y2 - Y1) - (X2 - X1)。
            担当者(I、0、DIS)ANS = MAX(ANS、DP [X2] [Y2 - I] [LEN])。
        } 
        のprintf(" %D \ n "、ANS * ANS)。
    }
    リターン 0 
}
コードの表示

 

おすすめ

転載: www.cnblogs.com/Willems/p/12307668.html