cogs 1199選課(樹形dp 揹包或多叉轉二叉

2022-08-01 22:54:16 字數 1524 閱讀 4503

題意:給m門課,每門課在上完其先修課後才能上,要你從中選n門課使得總學分盡可能大。

思路:揹包,沒有先修課看成其先修課編號為0,求乙個f[0][n]的揹包,表示以0為根的樹選n個結點的最大總權值,設x為根,y為x的孩子,對每個孩子,dfs(y),然後f[[x][t]=max(f[x][t],f[x][t-j]+f[y][j])用每個孩子更新x,最後若x不是0,再用自己的權值更新自己。但揹包好像不能記錄路徑。

1 #include2

#define rep(i,a,b) for(int i=a;i<=b;++i)

3#define dep(i,a,b) for(int i=a;i>=b;--i)

4using

namespace

std;

5const

int maxn=310;6

intread()

13int

n,m;

14int

v[maxn];

15 vectorson[maxn];

16int

f[maxn][maxn];

17void

init()24}

25void dp(int

x)35

if(x!=0) dep(t,m,1) f[x][t]=f[x][t-1]+v[x];36}

37int

main()

view code

多叉轉二叉,左孩子右兄弟。

若選根結點,f[i][j] = f[br[i][j]

若不選根結點,f[i][j] = f[ch[i]][k]+f[br[i]][j-1-k]+v[i]

遞迴尋找路徑方法類似。

1 #include2

#define rep(i,a,b) for(int i=a;i<=b;++i)

3#define dep(i,a,b) for(int i=a;i>=b;--i)

4using

namespace

std;

5const

int maxn=510;6

intread()

13int

n,m;

14int

v[maxn];

15int

br[maxn],ch[maxn];

16bool

ans[maxn];

17int

f[maxn][maxn];

18void

init()

28 memset(f,-1,sizeof

f);29}30

void dp(int x,int

y)33

dp(br[x],y);

34 rep(i,0,y-1)39

}40void path(int x,int

y)51}52

}53}54

intmain()

view code

(選課)揹包類樹形dp

選課 學校實行學分制。每門的必修課都有固定的學分,同時還必須獲得相應的選修課程學分。學校開設了 n 門的選修課程,每個學生可選課程的數量 m 是給定的。學生選修了這 m 門課並考核通過就能獲得相應的學分。在選修課程中,有些課程可以直接選修,有些課程需要一定的基礎知識,必須在選了其他的一些課程的基礎上...

選課(樹形DP)

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

樹形dp 選課

題目描述 description 學校實行學分制。每門的必修課都有固定的學分,同時還必須獲得相應的選修課程學分。學校開設了n n 300 門的選修課程,每個學生可選課程的數量m是給定的。學生選修了這m門課並考核通過就能獲得相應的學分。在選修課程中,有些課程可以直接選修,有些課程需要一定的基礎知識,必...