題目在這裡:http://acm.hdu.edu.cn/showproblem.php?pid=1520
題解,這是我的備忘錄,沒有任何注釋。
1 #include <iostream> 2 #include <vector> 3 #include <cstring> 4 5 using namespace std; 6 7 8 /* 9 dp[i][1] = max(dp[i parent][0] + score[i]) 10 dp[i][0] = max(dp[i parent][1], dp[i parent][0]) 11 12 13 if i 去:則對於其每一個孩子節點j而言,j是不能去的 14 dp[i][1] = sum(dp[j][0]) + score[i]; 15 else i 不去:則對於其每一個孩子節點j而言,j可以去可以不去,選擇快樂值較大的方案 16 dp[i][0] = sum(max(dp[j][0], dp[j][1])); 17 */ 18 19 const int MAX_N = 6000; 20 int score[MAX_N + 1]; 21 std::vector< std::vector<int> > graph(MAX_N + 1, std::vector<int>(0, 0)); 22 int parent[MAX_N + 1]; 23 24 int n; 25 int dp[MAX_N + 1][2]; 26 27 void treeDP(int node) 28 { 29 dp[node][1] = score[node]; 30 dp[node][0] = 0; 31 32 for (int i = 0; i < graph[node].size(); ++i) 33 treeDP(graph[node][i]); 34 35 for (int i = 0; i < graph[node].size(); ++i) 36 { 37 int child = graph[node][i]; 38 39 dp[node][1] += dp[child][0]; 40 dp[node][0] += max(dp[child][0], dp[child][1]); 41 } 42 } 43 44 int main(int argc, char const *argv[]) 45 { 46 while (cin >> n) 47 { 48 memset(score, 0, sizeof(int) * (MAX_N + 1)); 49 memset(parent, 0, sizeof(int) * (MAX_N + 1)); 50 memset(dp, 0, sizeof(int) * (MAX_N + 1) * 2); 51 for (int i = 1; i <= n; ++i) 52 { 53 cin >> score[i]; 54 graph[i].clear(); 55 } 56 57 int l, k; 58 while (true) 59 { 60 cin >> l >> k; 61 62 if (l == 0 && k == 0) 63 break; 64 else 65 { parent[l] = k; 66 graph[k].push_back(l); 67 } 68 } 69 70 // find root node 71 int root = 1; 72 while (parent[root] != 0) 73 root = parent[root]; 74 75 treeDP(root); 76 77 cout << max(dp[root][0], dp[root][1]) << endl; 78 } 79 return 0; 80 }