題解:這題算是比較裸的一道題,我們可以很明顯的看出來題目是一棵樹,所以我們可以先建一顆樹,然後從下往上進行轉移,這時候就要用到樹形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 ...