标签:
7 4
2 2
0 1
0 4
2 1
7 1
7 6
2 2
13
1 B[b] = C[a]; 2 C[a] = b;
建完树后就可以用记忆化搜索了。用F(i, j)表示以i为根节点的子树选j门课程的最多学分,A[i]表示第i门课程的学分,则方程为:
F(i, j) = max{ F(B[i], j), max{F(C[i], k) + F(B[i], j-k-1) + A[i]} (0≤k≤j-1) };
1 #include <iostream> 2 using namespace std; 3 int F[501][501]; 4 int A[501]; 5 int B[501]; 6 int C[501]; 7 int m, n; 8 void dfs(int p, int k) 9 { 10 if (F[p][k] != -1) 11 return; 12 else if (k == 0) { 13 F[p][k] = 0; 14 return; 15 } 16 else if (p == 0) 17 return; 18 else { 19 dfs(B[p], k); 20 F[p][k] = F[B[p]][k]; 21 for (int j = 0; j != k; ++j) { 22 dfs(C[p], j); 23 dfs(B[p], k - j - 1); 24 if (F[C[p]][j] + F[B[p]][k - j - 1] + A[p] > F[p][k]) 25 F[p][k] = F[C[p]][j] + F[B[p]][k - j - 1] + A[p]; 26 } 27 } 28 } 29 int main() 30 { 31 cin >> n >> m; 32 for (int i = 0; i <= n; ++i) 33 for (int j = 0; j <= m; ++j) 34 F[i][j] = -1; 35 for (int i = 1, a; i <= n; ++i) { 36 cin >> a >> A[i]; 37 if (a == 0) 38 a = n + 1; 39 B[i] = C[a]; 40 C[a] = i; 41 } 42 dfs(C[n + 1], m); 43 cout << F[C[n + 1]][m]; 44 return 0; 45 }
标签:
原文地址:http://www.cnblogs.com/smileandyxu/p/5348599.html