hihoCoder#1055 刷油漆

原题地址

 

第一次做树的动归题,如果没有提示的话还是挺难的

提示里的递推式隐含了状态压缩(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 }

 

你可能感兴趣的:(code)