この物語は、すべてJiekeの暴力(ドゥ)力(劉)DPを教えてくれる。
まず第一に、効果のタイトルは、私たちは彼に完全なバイナリツリーに変身するいくつかの方法を与えられたことです。我々は、すべての完全なバイナリツリーのリーフノードは、一方が鎖であり、他方は他方の鎖の深さよりも大きいチェーン1上の点の深された二本鎖であり、2つだけの場合があるべきで、互いに接続されています。
オーダーDP(i、j)がiノードの状態がjにおける動きの最小数で表します。
ステータスは何も3種類:
チェーン1深いです。
2.浅いチェーン。
3.二つの鎖。
私たちは、木のサブツリー内のリーフノードのすべての深さは上の値を、対応する場合、状態1と状態2のために、何の再帰がダウンして、ちょうど見ないようにしてポイントを、どんなにモバイル、深さは、常に同じではないことに注意してくださいそれは。
第三の場合は、以下の6例転送である:
1.1 2 +
2.1 3 +
3.3 + 2
4.2 + 1(1)
5.3 + 1(1)
6.2 + 3(1)に加えて、左右のサブツリーを指し交換過ごし
以下のコードを:
#pragma GCCの最適化( "Ofast、高速数学") の#pragma GCC対象( "AVX、AVX2") の#pragma GCCの最適化( "O2") の#include <ビット/ STDC ++。H> の#defineのGC PA == PB &&( PB =(PA = BUF)+関数fread(BUF、1,1- << 17、STDIN)、PA == PB)EOF:* PA ++ 静的チャーBUF [1 << 17]、* PA(BUF)、* PB (BUF)。 インラインint型リード(){ F = 1、INT S = 0を登録します。 チャーCH(GC)を登録します。 一方、(CH < '0' || CH> '9')CH == ' - ' F = -1、CH = GC:CH = GC。 一方、(CH> = '0' && CH <= '9')S = sの* 10 + CH-48、CH = GC。 リターンS *のF; } 名前空間stdを使用。 構造体yuansu { int型X、Y。 }扁[200005]。 int型ミネソタ州(10000000)。 int型B [100005]、DUI [100005]、deepth [100005]。 [100005] LEF int型、リグ[100005]。 int型のF(1)。 整数nを、X、Y。 可能INT [100005] [2]。 int型CMP(yuansu、yuansu B){ 戻りAX <BX。 } INT分(INT A、INT B){ ?<B戻り:Bと、 } BFS(){int型 int型ヘッド(1)、尾部(2) B [0] = Bは、[1] = 1。 DUI [1] = 1。 (!ヘッド=尾){ながら I(DUI [ヘッド])がINT。 もし{(LEF [I]!) IF(ミネソタ州= 10000000!){ IF((ミネソタ州> deepth [DUI [ヘッド] + 1)||(ミネソタ州<deepth [DUI [頭]] - 1))リターン1 ; } IF(ミネソタ州= deepth [DUI [ヘッド] &&ミネソタ州= 10000000!)F = 0。 ミネソタ州=分(ミネソタ州、deepth [DUI [頭部])。 } (!リグ[I])であれば{ IF(!ミネソタ州= 10000000){ IF((ミネソタ州> deepth [DUI [ヘッド] + 1)||(ミネソタ州<deepth [DUI [頭]] - 1))リターン1; } IF(!ミネソタ州= deepth [DUI [ヘッド] &&ミネソタ州= 10000000)、F = 0。 ミネソタ州=分(ミネソタ州、deepth [DUI [頭部]]); } IF {(!B [LEF [I]) DUI [尾部] = LEF [I]; deepth [DUI [尾] = deepth [DUI [ヘッド] + 1; 尾++; } IF {(!B [RIG [I]) DUI [尾部] = RIG [I]; deepth [DUI [尾] = deepth [DUI [ヘッド] + 1; 尾++ ; } ヘッド++; } 戻り0; } ボイドDFS(INT淀){ IF {(LEF [ディアン]!) IF(deepth [ディアン] ==ミネソタ州) の可能性[ディアン] [0] = 1; //場合ポイント不可能な浸透状態を含むサブツリーの光の点として、点(すなわち、状態0) 他 の可能な[ディアン] [1] = 1; } そう 考え[ディアン] [1] = 1。。。 {(RIG [ディアン]!)IF IF([ディアン] deepth ==ミネソタ州) 可能[ディアン] [0] = 1; int型のANS(100000000)。 } {([ディアン] LEF)であれば 、DFS([ディアン] LEF)。 可能[ディアン] [0] | =可能[ディアン] LEF] [0]。 可能[ディアン] [1] | =可能[ディアン] LEF] [1]。 } IF(リグ[ディアン]){ DFS(リグ[ディアン])。 可能[ディアン] [0] | =可能[リグ[ディアン] [0]。 可能[ディアン] [1] | =可能[リグ[ディアン] [1]。 } を返します。 } ボイドchushihua(){ DFS(1)。 返します。 } INT violence_dp(INTディアン、INT ZT){ IF(ZT == 0 || ZT == 1){ (!可能[ディアン] [ZT])であれば0を返します。 他に100000000を返します。 }他{ IF(LEF [ディアン] == 0 &&リグ[ディアン] == 0)100000000を返します。 それ以外の場合(![ディアン] &&リグLEF [ディアン]){ IF(deepth [ディアン] ==ミネソタ州){ ANS =分(ANS、violence_dp(リグ[ディアン]、0)+1); // 1 + 0(+1) ANS =分(ANS、violence_dp(リグ[淀]、2)+1); // 1 + 2(+1) }他{ ANS =分(ANS、violence_dp(リグ[ディアン]、1)); // 0 + 1つの ANS =分(ANS、violence_dp(リグ[ディアン]、2)); // 0 + 2 } !}そうであれば(LEF [ディアン] &&リグ[ディアン]){ IF(deepth [ディアン] ==ミネソタ州){ ANS =分(ANS、violence_dp( LEF [ディアン]、0)); // 0 + 1つの ANS =分(ANS、violence_dp([ディアン] LEF 2)); // 2 + 1 }他{ ANS =分(ANS、violence_dp(LEF [淀]、1)+1); // 1 + 0(+1) ANS =分(ANS、violence_dp(2)+1)、[ディアン] LEF; // 2 + 0(+1) } }他{ ANS =分(ANS、violence_dp(LEF [ディアン]、0)+ violence_dp(リグ[ディアン]、1)); // 0 + 1つの Y =読み取り(); ANS =分(ANS、violence_dp(LEF [ディアン]、2)+ violence_dp(リグ[ディアン]、1)); // 2つの+ 1つの ANS =分(ANS、violence_dp(LEF [ディアン]、0)+ violence_dp(リグ[ディアン]、2)); // 0 + 2つの ANS =分(ANS、violence_dp(LEF [ディアン]、1)+ violence_dp(リグ[ディアン]、0)+1); // 1 + 0(+ 1) ANS =分(ANS、violence_dp(LEF [ディアン]、1)+ violence_dp(リグ[ディアン]、2)+1); // 1 + 2(+1) ANS =分(ANS、violence_dp(LEF [淀]、2)+ violence_dp(リグ[ディアン]、0)+1); // 2 + 0(+1) } 戻りANS。 } } int型のmain(){ freopenは( "mobiles.in"、 "R"、STDIN)。 freopenは( "mobiles.out"、 "W"、STDOUT)。 N =読み取ります(); 以下のために(INT i = 1; iが<= N; iは++){ X =)(読み取ります。 (X> 0){もし [I] = xでLEF。 } であれば(Y> } } IF(BFS()){ 1 - COUT <<; 0を返す; } chushihua(); IF(F){//判定ではありません完全なバイナリ COUT << 0; 戻り0; } IF(violence_dp(1,2)> 10000000)COUT << - 1; 他のCOUT << violence_dp(1,2); 戻り0; }
}
Chushihua();
IF(F){//判定が満杯バイナリない
COUT << 0、
0を返す;
}
。(violence_dp(1,2)> 10000000)COUT << IF - 1;
他のCOUT << violence_dp (1,2);
戻り0;
}