樹上揹包兩題詳解

2021-10-22 04:57:06 字數 1578 閱讀 9156

題解:這題算是比較裸的一道題,我們可以很明顯的看出來題目是一棵樹,所以我們可以先建一顆樹,然後從下往上進行轉移,這時候就要用到樹形dp了,我們可以看到題目是會有好幾顆樹的,也就是森林,所以我們可以建乙個0點,把這個森林連成一棵樹,這時0是必選的(可以好好思考下這個點),所以這時我們是要選m+1節課,這時我們可以從下往上進行轉移,這時問題有來了,假如a是b的父親,b也有好幾個孩子,那麼選b的那幾個孩子是最好的那(注意必須要選b),這個問題是不是很像揹包?沒錯,這時候我們只需要在這裡進行乙個揹包,問題就解決了,我們可以接著向上轉移。

#include

using

namespace std;

int n, m;

int head[

1005];

int cnt =1;

int z[

305]

;int f[

305]

;vector<

int> q[

305]

;int dp[

305]

[305];

//第i個點選了幾節課

void

dfs(

int a)}}

}int

main()

dfs(0)

; cout << dp[0]

[m +1]

;}

題解:這個題和上面的題基本一樣,如果你理解了上面這個題那麼這個題是很簡單的,唯一的不同在於dfs是返回值的,當然上面的那個題也是可以這麼寫的,反而可以剪掉一些不存在的情況,具體我就不多講了,看**。

#include

using

namespace std;

const

int maxn =

1e5+5;

int n, m;

struct node

e[maxn]

;int head[maxn]

;int f[maxn]

;int dp[

3005][

3005];

//第i個點給幾個人看

int z[

3005];

int cnt =1;

void

add(

int u,

int v,

int w)

; head[u]

= cnt++;}

intdfs

(int a)

int sum =0;

for(

int i = head[a]

; i;i=e[i]

.next)}}

return sum;

}int

main()

}for

(int i = n-m+

1; i <= n;i++

)for

(int i =

1; i <= n; i++

)dfs(1

);for(

int i = m; i >=

1;i--)}

}

樹上揹包練習

p2014 ctsc1997 選課 p2014 ctsc1997 選課 solution 樹上揹包模板題 因為有多節課是沒有先修課的,所以並不是只有一棵樹,用乙個0號點作為沒有先修課的課程的先修課,這樣就合併成了一棵樹,只要選取m 1個點 必選0 即可。轉移方程 dp u j max dp u j ...

20171126,一二兩題

題目描述 萬聖節又到了!fj打算帶他的奶牛去參加乙個化裝晚會,但是fj只做了一套能容下兩頭總長不超過 s 的牛的恐怖服裝。fj養了 n 頭按 1.n 順序編號的奶牛,編號為 i 的奶牛的長度為 li。如果兩頭奶牛的總長度不超過 s,那麼她們就能穿下這套服裝。fj想知道,如果他想選擇兩頭不同的奶牛來穿...

重建道路 樹上揹包

初始化 void init struct edges edge maxm 1 無向圖則需要乘2 inline void add int u,int v head u cnt int dp m m siz m tmp m int n,m void dfs int u,int fa siz u siz ...