DP 樹形DP luogu2014 選課

2021-09-29 22:49:27 字數 2131 閱讀 1989

學生要在n門課程中選m門課程,每門課程最多依賴於一門前置課程(可以有多門課程沒有前置課程),問能獲得的最大學分是多少。(1<=m<=n<300)

顯然,每門課程依賴至多一門,有課程可以沒有依賴,所以這是乙個多叉樹森林

森林不太好處理,所以我們可以給森林加個虛擬根節點#0,讓每棵樹的根節點連到這個總結點上。問題即轉化為在這個多叉樹#0上選m門課程的最大學分,自然而然地,我們得到了dp狀態dpi

,j

dp_dp

i,j​

,即在i子樹上選擇j門課程可以得到的最大學分

按照二叉樹的思維來想,i子樹的j門課程可以分配給它的子樹們,即

d p[

i][j

]=∑d

p[so

ni][

ki]+

pnt[

i],w

here

∑ki=

j−

1dp[i][j] = \sum dp[son_i][k_i] + pnt[i]\ , \ where \ \sum k_i = j - 1

dp[i][

j]=∑

dp[s

oni​

][ki

​]+p

nt[i

],wh

ere∑

ki​=

j−1但顯然,由於i子樹可能有很多兒子,這樣排列組合下來複雜度很高,所以這樣不可取。當然,多叉樹直接算的辦法還是有的,但我目前沒有完全理解(確實不好理解)。事實上,我們可以曲線救國。既然二叉樹的辦法套在多叉樹上不好用,那我們就乾脆把多叉樹變成二叉樹——孩子兄弟樹

孩子兄弟樹,即左子樹是孩子,右子樹是兄弟。顯然,選i子樹的孩子課程就得選父親課程,但是選兄弟課程就不會受i子樹的影響,因此dp狀態dpi

,j

dp_dp

i,j​

,即在i子樹(i和i的孩子、i的兄弟)上選擇j門課程可以得到的最大學分,轉移式為

d p[

i][j

]=

dp[i][j] = \begin dp[bro_i][j]\\ max \ \end

dp[i][

j]=​

對應上式的情況分別為

不選課程i,只選i兄弟的課程

選i課程, 再選 i的孩子課程和兄弟課程共計j-1門

此處採取了dfs的方式保證了遍歷順序,準確的講是記憶化搜尋

# include

# include

# include

# include

using

namespace std;

const

int maxn =

310;

int fa[maxn]

, son[maxn]

, bro[maxn]

, val[maxn]

;//fa是不必要的

int dp[maxn]

[maxn]

;inline

void

add(

int f,

int s)

intdfs

(int i,

int j)

intmain()

printf

("%d\n"

,dfs(0

, m +1)

);system

("pause");

return0;

}

(多叉樹轉二叉樹,大讚!)

(分析了兩種方法,多叉/二叉)

(多叉樹法,分析得不錯,但多叉有個地方我理解不了~)

選課 P2014 樹形DP

在大學裡每個學生,為了達到一定的學分,必須從很多課程裡選擇一些課程來學習,在課程裡有些課程必須在某些課程之前學習,如高等數學總是在其它課程之前學習。現在有n門功課,每門課有個學分,每門課有一門或沒有直接先修課 若課程a是課程b的先修課即只有學完了課程a,才能學習課程b 乙個學生要從這些課程裡選擇m門...

P2014 選課(樹形DP)

傳送門 樹形dp入門題。這類題目被稱為揹包樹形dp,又稱有樹形依賴的揹包問題。雖說是入門題,但第一次寫並不是很順利,網上的解法都是二維的,但我只會先用高維做再轉成低維的,搞的就很難受。三維解法,思路見注釋 include include include define maxn 305 using n...

DP 樹形DP luogu2015 二叉蘋果樹

一棵二叉蘋果樹,邊上結了蘋果需要砍去一些邊,求保留q條邊時最多能保留多少蘋果。1 n,q 100 2 5 3 4 1題目保證了原始蘋果樹有分叉則必為二叉,且1為root注意輸入時父子順序是不確定的,所以需要做處理 定義d pi j dp dp i,j 表示編號為i的子樹在保留j條邊的情況下獲得的最大...