序文
この記事では主に、動的プログラミングツリーDP、DAG上のDP、デジタルDPの一元化された高度なモデルを紹介します。以前の基本モデルと異なる点の1つは、それらの状態が単に線形関係または2次元空間に基づいているのではなく、ツリー構造、グラフ、および2進数で転送されることです。薬を変えずにスープを変える。
サブディレクトリのリスト
1.ツリーDP
2. DAGのDP
3.デジタルDP
4.2.3ツリー/ DAG /デジタルDP
1.ツリーDP
名前が示すように、ツリー構造の動的プログラミングは、古典的な例で直接紹介されている概念はほとんどありません。
[上司のいないプロム]大学には 1人から n 人の n 人の従業員がい ます。それらの間には従属関係があります。つまり、それらの関係はプリンシパルをルートとするツリーのようなものであり、親ノードは子ノードの直接の上位です。アニバーサリーバンケットが開催され、バンケットに招待されたすべての従業員は特定の幸福指数aiを増やしますが、特定の従業員の上司がボールに来た場合、従業員はとにかくボールに来ません。したがって、幸福指数を最大化するために招待される従業員をプログラムして計算し、最大の幸福指数を求めてください。
ツリー構造で子を見つけるという問題は、実際には非常に便利です。すべてのノードは、子と唯一の親ノードにのみ接続されています。このプロパティを使用して切り込みます。iをルートとするツリーが子ツリーであると仮定します。ダンスに参加している場合、その場合、そのすべての子ノードは参加できません。参加しない場合、子ノードは参加するかどうかに関係なく、そのすべての子ノードに再帰的に続きます。
状態の定義:f [i]は、「iをルートノードとするサブツリーによって取得できる最大幸福度インデックス」を意味します。
どのノードにも参加と非参加の2つの状態があるため、ダンスに参加するかどうかを示すために、1次元の0/1も必要です。
状態遷移:f [i] [0] = ∑max(f [j] [0]、f [j] [1]);
f [i] [1] = ∑f [j] [0] + a [i] 、jはiの子ノードを表します。
コード:
1 #include <bits / stdc ++。h> 2 名前空間std を使用 。 3 4 #define MAXN 6005 5 6 struct Edge { 7 int v、nxt; 8 } e [MAXN]; 9 10 int n、o、u、v、tot、f [MAXN] [ 2 ]、nr [MAXN]、h [MAXN]; 11 12 void addEdge(int u、int v){ 13 e [++ o] =(Edge){v、h [u]}、h [u] = o; 14 } 15 16 void dfs(int o、 int fa){ 17 for(int x = h [o]; x; x = e [x] .nxt){ 18 int v = e [x] .v; 19 であれば(V == FA)を続けます。 20 dfs(v、o); 21 f [o] [ 1 ] + = f [v] [ 0 ]; 22 f [o] [ 0 ] + = max(f [v] [ 0 ]、f [v] [ 1 ]); 23 } 24 } 25 26 int main(){ 27 cin >> n; 28 のために(int i = 1 ; i <= n; i ++)cin >> f [i] [ 1 ]; 29 for(int i = 1 ; i <= n; i ++ ) 30 cin >> u >> v、addEdge(v、u)、nr [u] = 1 ; 31 for(int i = 1 ; i <= n; i ++ ){ 32 if(nr [i])continue ; 33 dfs(i、0 ); 34 cout << max(f [i] [ 0 ]、f [i] [ 1 ]); 35 休憩; 36 } 37 return 0 ; 38 }
2. DAGのDP
3.デジタルDP