樹形dp 選課

2022-05-12 03:43:59 字數 1323 閱讀 8748

題目描述 description

學校實行學分制。每門的必修課都有固定的學分,同時還必須獲得相應的選修課程學分。學校開設了n(n<300)門的選修課程,每個學生可選課程的數量m是給定的。學生選修了這m門課並考核通過就能獲得相應的學分。 

在選修課程中,有些課程可以直接選修,有些課程需要一定的基礎知識,必須在選了其它的一些課程的基礎上才能選修。例如《frontpage》必須在選修了《windows操作基礎》之後才能選修。我們稱《windows操作基礎》是《frontpage》的先修課。每門課的直接先修課最多只有一門。兩門課也可能存在相同的先修課。每門課都有乙個課號,依次為1,2,3,…。 例如: 

【詳見】

表中1是2的先修課,2是3、4的先修課。如果要選3,那麼1和2都一定已被選修過。   你的任務是為自己確定乙個選課方案,使得你能得到的學分最多,並且必須滿足先修課優先的原則。假定課程之間不存在時間上的衝突。

輸入描述 input description

輸入檔案的第一行包括兩個整數n、m(中間用乙個空格隔開)其中1≤n≤300,1≤m≤n。 

以下n行每行代表一門課。課號依次為1,2,…,n。每行有兩個數(用乙個空格隔開),第乙個數為這門課先修課的課號(若不存在先修課則該項為0),第二個數為這門課的學分。學分是不超過10的正整數。

輸出描述 output description

輸出檔案只有乙個數,實際所選課程的學分總數。

樣例輸入 sample input

7 42 2

0 10 4

2 17 1

7 62 2

樣例輸出 sample output

13//

建樹需要技巧,建左兒子右兄弟樹(大概是叫這個名字吧)

狀態轉移方程:

ma=max(ma,f(sub[a].so,l-i)+f(sub[a].br,i-1)+sub[a].sc);

// 如果選課,進入其子節點運算,將返回值與兄弟節點運算的返回值、自身的學分求和,得組合的最大值

ma=max(ma,f(sub[a].br,l));

//如果不選,不進入其子節點,其餘同上

//**如下

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

struct psub[400];

int dp[650][650];

int f(int a,int l)

return dp[a][l]=max(ma,dp[a][l]);

}int main()//如果這個點的父節點已經有子節點,將其排入子節點的兄弟節點 }

cout<

選課(樹形DP)

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

codevs1378 選課 樹形DP

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

code vs 1378 選課(樹形DP)

時間限制 1 s 空間限制 128000 kb 題目等級 鑽石 diamond 題解 檢視執行結果 學校實行學分制。每門的必修課都有固定的學分,同時還必須獲得相應的選修課程學分。學校開設了n n 300 門的選修課程,每個學生可選課程的數量m是給定的。學生選修了這m門課並考核通過就能獲得相應的學分。...