樹狀DP個人總結

2021-09-22 19:31:23 字數 2700 閱讀 3760

樹狀dp就是在樹上的動態規劃,樹狀dp的特殊性:無環,dfs不會重複,具有明顯嚴格的層數關係。

大神的好文:

大神的好文:

什麼時候用樹狀dp?

什麼題目滿足動態規劃的要求?

子問題最優解也是全域性最優解,滿足無後效性,多階段決策問題。把問題首先分解為若干個子問題,在每乙個子問題做                 出決 策,動態規劃就是解決多階段決策最優解的一種方法。

階段:將所給問題的過程,按時間或空間(樹歸中是空間,即層數)特徵分解成若干相互聯絡的階段,以便按次序去求每階                    段的解。

狀態:各階段開始時的客觀條件叫做狀態。

決策:當各段的狀態取定以後,就可以做出不同的決定,從而確定下一階段的狀態,這種決定稱為決策。 (即孩子節點和父親節點的關係)

策略:由開始到終點的全過程中,由每段決策組成的決策序列稱為全過程策略,簡稱策略。

狀態轉移方程:

前一階段的終點就是後一階段的起點,前一階段的決策選擇匯出了後一階段的狀態,這種關係描述了由k階段到k+1階  段 (在樹中是孩子節點和父親節點)狀態的演變規律,稱為狀態轉移方程。

目標函式與最優化概念:

目標函式是衡量多階段決策過程優劣的準則。最優化概念是在一定條件下找到乙個途徑,經過按題目具體性質所確定的運算以後,使全過程的總效益達到最優。

樹的特點及性質:

有n個點,n-1條邊的無向圖,任意兩個頂點之間可達。

無向圖中任意兩個點間有且只有一條路。

乙個點至多有乙個前驅,但可以有多個後繼。

無向圖無環。

poj - 2342 

首先理解題意: 如何選擇使得最終得到的歡樂值最大?題目要求:下屬和他的直接領導不能被一起選擇。下面看一下樣例:n,下面輸入n行,每行代表乙個人對應的歡樂值,再下面輸入n-1行代表對應的關係,並且以0 0輸入結束。

思路:按照大神給的步驟:首先這道題是否是資料結構對應樹的關係,根據主管關係可以判斷滿足對應樹的關係。是否是動態規劃問題?

滿足動態規劃要求,最大歡樂值,無後效性,最優解,有子問題。接下來分析狀態,每個狀態都有選擇和不選擇兩種狀態,任何乙個點的取捨都有兩種狀態,dp[i][0]表示第i個人不選擇所獲得的最大歡樂值,dp[i][1]表示第i個人選擇所獲得的最大歡樂值,

dp[node][0]+=max(dp[i][0],dp[i][1]),dp[node][1]+=dp[i][0];儲存方式:節點數目多餘5000個,最好採用鄰接表儲存,建議使用vector儲存。

#include#include#include#includeusing namespace std;

const int maxn=6001;

int n;

int dp[maxn][3];

//dp[i][0]表示第i個人不選擇所獲得的最大歡樂值

//dp[i][1]表示第i個人選擇所獲得的最大歡樂值

int father[maxn];

int vis[maxn];

void dfs(int node)

}}int main()

int son,fath,root;

bool beg=1;

root=0;

while(cin>>son>>fath,son||fath)

}while(father[root])//查詢父親節點

root=father[root];

dfs(root);

int ans=max(dp[root][0],dp[root][1]);

printf("%d\n",ans);

} return 0;

}

其實這道題和上一道題目型別很像,動態規劃方程都很像,原理也基本一樣,只是方法,用的是vector方法。

思路,是否滿足動態規劃的要求,是否是樹狀結構,接下來考慮儲存方式,不論是vector類似於鄰接表還是用一維陣列代替都可以。接下來考慮動態規劃方程,同樣的也是有兩種狀態,dp[node][0]表示以node為根在node上不放置士兵所需的最小士兵數目,dp[node][1]表示以node為根在node上放置士兵所需的最小士兵數目。i是node的兒子,dp[node][0]+=dp[i][1],父親上不放置,兒子上一定要放置。注意看清題意,是樹的點覆蓋問題。dp[node][1]+=min(dp[i][0],dp[i][1])。我覺得主要難的是處理結點以及邊的一些細節問題。

#include#include#include#include#includeusing namespace std;

typedef long long ll;

const int maxn=1501;

vectormp[maxn];

ll dp[maxn][3];

ll father[maxn];

ll vis[maxn];

ll n;

void dfs(ll node)

}// cout<<1

while(father[root]!=-1)

root=father[root];

//cout

// cout

// cout

}

樹狀陣列的個人總結

模板組成 模板構成 lowbit x 返回 x的最低位1 eg 2 0 2 1 2 2 updata int x,int val 更新資料 while x n 更新的時候我們要更新包含 a x 的所有c x 查詢父節點的時候我們就需要 lowbit c x val x lowbit x 如果我們在a...

樹狀dp入門

description 實驗室被zser大魔王統治了,這天zser想選出一部分人看看他們對zser的恐懼值,不過實驗室中除了某雲飛之外每個人都有他最討厭的人,就像樹形結構一樣。zser選出的人中不能存在乙個人討厭乙個人。問zser選出的人可以帶來的最大恐懼值為多少。input 第1行1個正整數 n,...

dp 樹狀陣列

給定乙個長度為 n n 的序列 a a 求 a a 有多少個長度為 m m 的嚴格遞增子串行。輸入格式 第一行包含整數 t t t,表示共有 t t 組測試資料。每組資料,第一行包含兩個整數 n n 和 m m。第二行包含 n n 個整數,表示完整的序列 a a。輸出格式 每組資料輸出乙個結果,每個...