首页 > 代码库 > [codevs1378]选课

[codevs1378]选课

传送门

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 }

 

[codevs1378]选课