1>形質転換バイナリーツリー
ツリーは、上記の数を変更し、二分探索木の数になります
それ行きがけは厳密に増加します
まず、ソートは、バイナリツリーで、彼の息子の父親、バイナリツリー(BST)の父よりも厳密に大きい右の重量の息子よりも厳密に小さい右の値を左。
得られたバイナリツリートラバーサルシーケンスのいわゆる「仕分け」の並べ替えは厳密に増加するシーケンスです。
だから、明らかに我々は最初の配列Aを構築するために、旅行を予約限定しなければなりません、
そして、それは修正の必要最小限の数、厳密に増加順序を変更することが求めている課題となります
考え方を変えビュー暴力の私達のポイントを変更しないようにするためには、どのようなポイントを見て残すことができます
ここで残りの点、AJ-愛> = J-I、
この奇妙なああ、さらに変換:
[i]は-iその後、最も長いシーケンスは非減少できます
書式#include <cstdioを> する#include <cstdlib> 書式#include <アルゴリズム> 使用して 名前空間はstdを、 int型のn; CONSTの INT N = 1E5 + 3 。 INT D [N]、息子[N] [ 2 ]。 INT [N]、CNT。 int型[N]をアップ。 ボイド mid_dfs(int型POS) { 場合(息子[POS] [ 0 ])mid_dfs(息子[POS] [ 0 ])。 【 ++ CNT] = D [POS] - CNT。 もし(息子[POS] [ 1 ])mid_dfs(息子[POS] [ 1 ])。 } INT メイン() { scanfの(" %のD "、およびN-)を、 ため(INT I = 1 scanfの(; I <= N-Iが++)" %のD "、&D [I]); int型F、PS; のため(int型 I = 2 ; I <= N; Iは++ ) { scanfの(" %のD%のD "、&F、&PS); 息子[F] [PS] = I; } mid_dfs(1); // 単純なステップ、タイトル、実際に完全に変更された外観の int型 SZ = 1。; [アップ。1 [] = 1 ]; のため(int型 I = 2 ; Iは= CNTを<Iは++ ) { int型の POS = UPPER_BOUND、(+最大1、最大+ SZの+ 。1 - ;アップ、A [I])//がから尋ねます降順で、書き込みは、上部、>が変更されたときに確立==表される IF(POS> SZ)SZ ++ ; アップ【POSは] = [I]を、 } のprintf(" %d個の\ N- "、N- SZ)を、 リターン 0 ; }
2>比較スイッチング素子2つのスキーム
順序付きのシーケンスは、交換の数が最小必要ように、スイッチング素子
最初は、のみ交換「隣接」要素、交換の最小数を見つける整然と配列するように、
それは昇順のシーケンスである場合には、唯一の逆数を見つけます。
3 2 1-> 1 2 3
3回
4 2 3 1 - > 1 2 3 4
2 3 1 4(3)
1 2 3 4(1)
1 2 3 4(1)
各番号は正確に対応し、右の数は、彼の番号を逆にします
第二は、任意の二つの位置を交換するために、ので、順序付け、交換の必要最小限の数の要素を
答えは:環(置換された環)デジタル形式のN-交換の数。
(すなわち、すべての各データ交換のリング、数)
例えば、{51324768}は、配列は、配列交換を昇順に最小回数を見つけます
次いで、リングシーケンス{5,1,2,4}、{7,6}、{3}、{8}、その後交換の最小数は8-4であるを有し、
降順を求める交換の最小数は、単にの配列を逆にし、それを解決します。
3>エクスチェンジ
:コピー元https://www.cnblogs.com/Damitu/p/7646694.html
本当に疲れて、私は戦うためにしたくありません
問題の解決:
①逆を考え、多くの問題を考えるためにダウン:最後の交換位置が発生します
②メモリ検索、逆さまにした後、列挙為替の現在の状態がどのような位置で行われ、その後、2つのセクションに分かれたサブ問題に対処
③注:場所は左と右の交換は2つの部分で起こり得るである、それはいくつかの番号が含まれている必要があり(順不同でも可)
④伝達方程式:F [L] [R&LT] + = DFS(L、I)DFS * C [-rlは1である。] [IL](1 + Iは、R。)
現在の区間[L、R]、交換することをiは、iが+ 1、両側の独立決定するので、組合せ関係があり、放電空間に変換することができることを示しするプログラム番号nの数2Nを有し、これは、内側の各側面秩序ある(これは重要な結論です)。
#include <cstdioを> する#include <cstdlib> の#include <CStringの> する#include <アルゴリズム> 使用して 名前空間STDを、 int型のn; CONSTの INT N = 53、MOD = 1E9 + 7 。 int型ST [N]、ED [N]; INT [N] [N] C。 ボイドは()準備 { C [ 0 ] [ 0 ] = 1 。 以下のために(int型 i = 1 ; iが<= N; iは++ ) { C [i]が[ 0 ] = 1 ; にとって(のInt J = 1 ; J <= I; J ++ ) C [I] [J] =(C [I- 1 ] [J] + C [I- 1 ] [J- 1 ])%MOD; } } int型ANS; ロング ロングJL [N] [N]; ロング ロング DFS(int型 L、INT R&LT) { IF(JL [L] [R&LT]> = 0)リターン JL [L] [R&LT]; // マジックプラスメモリ IF(R&LT == L)リターン JL [L] [R&LT] = 1 ; JL [L] [R&LTが] = 0 。 用(int型 ; I <R iが++ iはLを= ) { スワップ(ST [i]は、ST [I + 1 ])。 int型J、K。 用 <;(J = J ++ J = L ) であれば(I ST [J])> ブレーク。 用(K = I + 1、K <= R; ++ k個) であれば(ST [K] <= I)破ります。 もし(J> I && K> R) { 長い 長い ANS1 = DFS(L、I)* DFS(I + 1、R)%MOD。 長い 長い ANS2 = ANS1 * C [RL- 1 ] [IL]%モッズ; JL [L] [R] =(JL [L] [R] + ANS2)%MOD。 } スワップ(ST [i]は、ST [I + 1 ])。 } 戻りJL [L] [R]。 } int型のmain() { scanf関数(" %のD "、&N) 用(int型 iは= 0 ; iがN <I ++は) のscanf(" %dの"、およびST [i])と、ED [I] = I。 準備()。 memset(JL、 - 1、はsizeof (JL))。 DFS(0、N- 1); printf(" %LLDする\ n "、JL [ 0 ] [N- 1 ])。 リターン 0 ; }