第一次做树的动归题,如果没有提示的话还是挺难的
提示里的递推式隐含了状态压缩(m从大往小遍历),不是那么好想,只能说不能再屌了。
代码:
1 #include <iostream> 2 #include <cstring> 3 4 using namespace std; 5 6 #define SIZE 128 7 8 int tree[SIZE][SIZE]; 9 int v[SIZE]; 10 int f[SIZE][SIZE]; 11 int N, M; 12 13 void traverse(int t, int p) { 14 f[t][0] = 0; 15 f[t][1] = v[t]; 16 17 for (int i = 1; i <= tree[t][0]; i++) { 18 int t_child = tree[t][i]; 19 if (t_child == p) 20 continue; 21 traverse(t_child, t); 22 for (int m = M; m >= 2; m--) { 23 for (int m_child = 1; m_child <= m - 1; m_child++) { 24 f[t][m] = max(f[t][m], f[t][m - m_child] + f[t_child][m_child]); 25 } 26 } 27 } 28 } 29 30 int main() { 31 int res = 0; 32 33 memset(tree, 0, SIZE * SIZE * sizeof(int)); 34 memset(f, 0, SIZE * SIZE * sizeof(int)); 35 36 cin >> N >> M; 37 for (int i = 1; i <= N; i++) 38 cin >> v[i]; 39 for (int i = 1; i <= N - 1; i++) { 40 int a, b; 41 cin >> a >> b; 42 tree[a][0]++; 43 tree[b][0]++; 44 tree[a][tree[a][0]] = b; 45 tree[b][tree[b][0]] = a; 46 } 47 48 traverse(1, -1); 49 cout << f[1][M] << endl; 50 51 return 0; 52 }
时间: 2024-10-06 04:13:01