|洛谷|動態規劃|P2014 選課
阿新 • • 發佈:2019-01-09
http://www.luogu.org/problem/show?pid=2014
(注意題目資料範圍有誤,建議開陣列到2000)
經典樹形依賴揹包問題。
因為可能出現森林,所有要建立一個虛結點0,將森林中所有樹的根節點作為結點0的兒子
f[i][j]表示以i為根選j個課程
f[u][j] = max(f[u][j], f[u][j-k]+f[v][k]); //v是u的兒子
#include<cstdio> #include<cstring> #include<algorithm> #include<vector> #define ms(i,j) memset(i, j, sizeof(i)); using namespace std; int n,m; int t; int w[2005]; vector<int>G[2005]; int f[2005][2005]; void dfs(int u) { for (int i=1;i<=m;i++) f[u][i] = w[u];//必選u for (int i=0;i<G[u].size();i++) { int v = G[u][i]; dfs(v); for (int j=t;j>=2;j--) { for (int k=1;k<j;k++) { f[u][j] = max(f[u][j], f[u][j-k]+f[v][k]); } } } } int main() { scanf("%d%d", &n, &m); for (int i=1;i<=n;i++) { int ki; scanf("%d%d", &ki, &w[i]); G[ki].push_back(i); } t = m+1;//增加了一個虛結點0,將森林轉為樹,所以t=m+1 dfs(0); printf("%d\n", f[0][m+1]); return 0; }