当前位置:   article > 正文

P2016 战略游戏——树状DP的使用

p2016 战略游戏

题面

树状DP是给树状结构的题做动态规划 找最值,因此要造一个树结构,我们可以用vector数组存储每个结点连接的边 造一个树出来,然后通过dfs不断遍历每个结点,对每个结点进行放置人或者不放置人操作,递归到根节点输出答案

建树+找根节点

  1. int n, a, b, z;
  2. cin >> n;
  3. for (int i = 1; i <= n; i++)
  4. {
  5. cin >> a >> b;
  6. ++a;
  7. for (int j = 1; j <= b; j++)
  8. {
  9. cin >> z;
  10. ++z;
  11. father[z] = 1;
  12. s[a].push_back(z);
  13. }
  14. }
  15. for (int i = 1; i <= n; i++)
  16. {
  17. if (father[i] == 0)
  18. {
  19. root = i;
  20. break;
  21. }
  22. }

dfs遍历并且对每个结点进行操作

对每个结点放置与不放置两种状态分别赋为1和0 然后继续向下搜索 回归累加最小值

  1. void dfs(int x)
  2. {
  3. res[x][0] = 0;
  4. res[x][1] = 1;
  5. if (s[x].size() == 0)
  6. return;
  7. for (int i = 0; i < s[x].size(); i++)
  8. {
  9. int y = s[x][i];
  10. dfs(y);
  11. res[x][0] += res[y][1];
  12. res[x][1] += min(res[y][1], res[y][0]);
  13. }
  14. }

AC代码

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const int N = 1700;
  4. int res[N][2];
  5. bool father[N];
  6. int root;
  7. vector<int> s[N];
  8. void dfs(int x)
  9. {
  10. res[x][0] = 0;
  11. res[x][1] = 1;
  12. if (s[x].size() == 0)
  13. return;
  14. for (int i = 0; i < s[x].size(); i++)
  15. {
  16. int y = s[x][i];
  17. dfs(y);
  18. res[x][0] += res[y][1];
  19. res[x][1] += min(res[y][1], res[y][0]);
  20. }
  21. }
  22. int main()
  23. {
  24. int n, a, b, z;
  25. cin >> n;
  26. for (int i = 1; i <= n; i++)
  27. {
  28. cin >> a >> b;
  29. ++a;
  30. for (int j = 1; j <= b; j++)
  31. {
  32. cin >> z;
  33. ++z;
  34. father[z] = 1;
  35. s[a].push_back(z);
  36. }
  37. }
  38. for (int i = 1; i <= n; i++)
  39. {
  40. if (father[i] == 0)
  41. {
  42. root = i;
  43. break;
  44. }
  45. }
  46. dfs(root);
  47. cout << min(res[root][0], res[root][1]);
  48. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Guff_9hys/article/detail/996514
推荐阅读
  

闽ICP备14008679号