(選課)揹包類樹形dp

2021-09-29 00:14:15 字數 1617 閱讀 8906

選課

學校實行學分制。

每門的必修課都有固定的學分,同時還必須獲得相應的選修課程學分。

學校開設了 n 門的選修課程,每個學生可選課程的數量 m 是給定的。

學生選修了這 m 門課並考核通過就能獲得相應的學分。

在選修課程中,有些課程可以直接選修,有些課程需要一定的基礎知識,必須在選了其他的一些課程的基礎上才能選修。

例如《windows程式設計》必須在選修了《windows操作基礎》之後才能選修。

我們稱《windows操作基礎》是《windows程式設計》的先修課。

每門課的直接先修課最多只有一門。

兩門課可能存在相同的先修課。

你的任務是為自己確定乙個選課方案,使得你能得到的學分最多,並且必須滿足先修條件。

假定課程之間不存在時間上的衝突。

輸入格式

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

接下來n行每行代表一門課,課號依次為1,2,…,n。

每行有兩個數(用乙個空格隔開),第乙個數為這門課先修課的課號(若不存在先修課則該項為0),第二個數為這門課的學分。

學分是不超過10的正整數。

輸出格式

輸出乙個整數,表示學分總數。

輸入樣例:

7 4

2 20 1

0 42 1

7 17 6

2 2

輸出樣例:

13
因為不止一門課程沒有先修課,所以這n門課程構成了森林結構,可以新建乙個「虛擬課程」---0號節點,作為實際上沒有先修課的先修課,這樣就構成了包含n+1個節點的樹。注意0號節點是沒有學分的,**1將課程數量m+1,所以從0號節點列舉體積的時候可以分配給0號節點1個體積;**2從0號節點列舉體積,將m個體積全部分給其子樹。

**1:

#include #include #include using namespace std;

const int n = 305;

vectorson[n];

int score[n],f[n][n];

int n,m;

void dp(int x)}}

for(int i=m;i>0;i--)

f[x][i]=f[x][i-1]+score[x];

f[x][0]=0;

}int main()

m++;

dp(0);

printf("%d",f[0][m]);

return 0;

}

**2:

#include #include #include using namespace std;

const int n = 305;

vectorson[n];

int score[n],f[n][n];

int n,m;

void dp(int x)}}

if(x)

}int main()

dp(0);

printf("%d",f[0][m]);

return 0;

}

acwing 286 選課(揹包類樹形dp)

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

選課 CH5402(揹包類樹形DP

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

luogu2014 選課 揹包類樹形DP

題目大意 有n門功課,每門課有個學分,每門課有一門或沒有直接先修課 若課程a是課程b的先修課即只有學完了課程a,才能學習課程b 乙個學生要從這些課程裡選擇m門課程學習,問他能獲得的最大學分是多少?對於每個節點u,定義u dp j 為在剩餘課程數為j,以u為根的子樹中能夠獲得的最高學分,則u dp j...