選課 P2014 樹形DP

2021-09-26 03:34:45 字數 1343 閱讀 4292

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

第一行有兩個整數n,m用空格隔開。(1<=n<=300,1<=m<=300)

接下來的n行,第i+1行包含兩個整數ki和si, ki表示第i門課的直接先修課,si表示第i門課的學分。若ki=0表示沒有直接先修課(1<=ki<=n, 1<=si<=20)。

只有一行,選m門課程的最大得分。

以0點為超級源點,然後向下跑樹形dp,注意的點是,只有選取該點才能往下走下去,此為先決條件。

#include #include #include #include #include #include #include #include #include #include #include #include #define lowbit(x) ( x&(-x) )

#define pi 3.141592653589793

#define e 2.718281828459045

#define inf 0x3f3f3f3f

#define half (l + r)>>1

#define lsn rt<<1

#define rsn rt<<1|1

#define lson lsn, l, mid

#define rson rsn, mid+1, r

#define ql lson, ql, qr

#define qr rson, ql, qr

#define myself rt, l, r

using namespace std;

typedef unsigned long long ull;

typedef long long ll;

const int maxn = 305;

int n, m, val[maxn], head[maxn], cnt;

struct eddge

}edge[maxn];

inline void addeddge(int u, int v)

int dp[maxn][maxn];

void dfs(int u, int res)}}

}inline void init()

int main()

dfs(0, m);

printf("%d\n", dp[0][m]);

return 0;

}

P2014 選課(樹形DP)

傳送門 樹形dp入門題。這類題目被稱為揹包樹形dp,又稱有樹形依賴的揹包問題。雖說是入門題,但第一次寫並不是很順利,網上的解法都是二維的,但我只會先用高維做再轉成低維的,搞的就很難受。三維解法,思路見注釋 include include include define maxn 305 using n...

題解 P2014 選課(樹形DP 拓撲)

題意 現在有n門功課,每門課有一定的價值,但是課程可能需要一門先修課,問選m門課程能獲得的最大價值。分析 剛剛開始我以為這道題可能會出現環的情況 如 haoi 2010軟體安裝,但是又不會tarjan,本欲放棄,但是忽然眼角餘光瞟到討論班裡有人說這道題沒有環 好吧,這樣就比較easy了。首先我們要用...

洛谷P2014 選課 樹形dp

給出n 300 n leq300 n 30 0個結點,每個結點都有乙個權值,然後一些結點必須只有選了前驅結點這個結點才可以被選。現在最多選m 300 m leq300 m 30 0個結點,求最大權值。實際上這個是乙個森林,但是通過設定乙個權值為0 00的虛點0 00,把所有的沒有前驅的點全部連到這個...