f[i][j]代表以在节点i和它的子树中选j门课时可以达到的最大学分。
1 #include<cstdio> 2 #include<vector> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 7 inline void read(int &ans) { 8 static char ch = getchar(); 9 register int neg = 1; 10 ans = 0; 11 for (; !isdigit(ch); ch = getchar()) 12 if (ch == ‘-‘) neg = -1; 13 for (; isdigit(ch); ch = getchar()) 14 ans = ans * 10 + ch - ‘0‘; 15 ans *= neg; 16 } 17 const int N = 310; 18 vector < int > g[N]; 19 int n, m, f[N][N], w[N]; 20 inline void init() { 21 read(n); read(m); 22 for (int a, i = 1; i <= n; ++i) { 23 read(a); read(w[i]); 24 g[a].push_back(i); 25 } 26 } 27 28 void dp(int u) { 29 int size = g[u].size(); 30 for (int i = 0; i < size; ++i) { 31 int &v = g[u][i]; 32 dp(v); 33 for (int j = m; j >= 1; --j) { 34 for (int k = 1; k <= j; ++k) { 35 f[u][j] = max(f[u][j], f[u][j - k] + f[v][k]); 36 } 37 } 38 } 39 if (u) for (int i = m; i >= 1; --i) f[u][i] = f[u][i - 1] + w[u]; 40 } 41 42 int main() { 43 init(); 44 dp(0); 45 printf("%d\n", f[0][m]); 46 return 0; 47 }
时间: 2024-11-05 11:36:23