左神算法进阶班5_3求公司的最大活跃度

【题目】

一个公司的上下节关系是一棵多叉树,这个公司要举办晚会,你作为组织者已经摸清了大家的心理:

一个员工的直接上级如果到场,这个员工肯定不会来。

每个员工都有一个活跃度的值,决定谁来你会给这个员工发邀请函,怎么让舞会的气氛最活跃?

返回最大的活跃值。

举例:

给定一个矩阵来表述这种关系

matrix =

{

1,6

1,5

扫描二维码关注公众号,回复: 6607920 查看本文章

1,4

}

这个矩阵的含义是:

matrix[0] = { 1 , 6 },表示0这个员工的直接上级为1, 0这个员工自己的活跃度为6

matrix[1] = { 1 , 5 },表示1这个员工的直接上级为1(他自己是这个公司的最大boss), 1这个员工自己的活跃度为5

matrix[2] = { 1 , 4 },表示2这个员工的直接上级为1, 2这个员工自己的活跃度为4

为了让晚会活跃度最大,应该让1不来,0和2来。最后返回活跃度为10

【题解】

使用动态规划

每个节点保存其活跃度

然后嘛整棵树按照等级进行展开

x1来的活跃度为:x1的活跃度 + x1所有子节点不来的活跃度

x1不来的活跃度:x1不来 + x1所有子节点的每个节点中的max(来,不来)

【代码】

  

  1 #pragma once
  2 #include <iostream>
  3 #include <vector>
  4 
  5 using namespace std;
  6 
  7 ///使用动态规划求解
  8 void process(vector<vector<int>>data, vector<vector<int>>&dp, vector<bool>isVist, int& root)
  9 {
 10     isVist[root] = true;//遍历过
 11     dp[root][1] = data[root][1];//获取活跃值
 12     for (int i = 0; i < data.size(); ++i)
 13     {
 14         if (data[i][0] == root && !isVist[i])
 15         {
 16             process(data, dp, isVist, i);
 17             dp[root][1] += dp[i][0];
 18             dp[root][0] += dp[i][0] > dp[i][1] ? dp[i][0] : dp[i][1];
 19         }
 20     }
 21 }
 22 
 23 
 24 int getMaxHappy(vector<vector<int>>data)
 25 {
 26     vector<vector<int>>dp(data.size(), vector<int>(data[0].size(), 0));
 27     vector<bool>isVist(data.size(), false);
 28     int root = 0;//找到boss
 29     for (int i = 0; i < data.size(); ++i)
 30         if (data[i][0] == i)//自己是自己的 上司,则此人为boss
 31         {
 32             root = i;
 33             break;
 34         }
 35     process(data, dp, isVist, root);
 36     return dp[root][0] > dp[root][1] ? dp[root][0] : dp[root][1];
 37 }
 38 
 39 
 40 ///使用二叉树的递归来求解
 41 struct Node
 42 {
 43     int val;//活跃度
 44     vector<Node*>child;//下属,是1:n的关系
 45     Node(int a) :val(a) {}
 46 };
 47 
 48 Node* Create(const vector<vector<int>>data)
 49 {
 50     Node* head = nullptr;
 51     vector<Node*>node(data.size());
 52     int root = 0;
 53     for (int i = 0; i < data.size(); ++i)
 54         if (data[i][0] == i)
 55         {
 56             root = i;
 57             break;
 58         }
 59     node[root] = new Node(data[root][1]);
 60     for (int i=0;i<data.size();++i)
 61     {
 62         if (data[i][0] != i)//不是大boss
 63         {
 64             node[i] = new Node(data[i][1]);
 65             node[data[i][0]]->child.push_back(node[i]);
 66         }
 67         else
 68             head = node[i];
 69     }
 70     return head;
 71 }
 72 
 73 
 74 struct returnType
 75 {
 76     int c;//来的活跃度
 77     int nc;//不来的活跃度
 78     returnType(int a, int b) :c(a), nc(b) {}
 79 };
 80 
 81 returnType* calMaxHappy(Node* head)
 82 {
 83     int cvalue, ncvalue;
 84     cvalue = head->val;//head去的活跃度
 85     ncvalue = 0;//head不去的活跃度
 86     for (int i = 0; i != head->child.size(); ++i)
 87     {
 88         returnType* res = calMaxHappy(head->child[i]);
 89         cvalue += res->nc;
 90         //上司去的活跃度 = 上司的活跃度 + 下属不去的活跃度;因为上司去,下属不会去
 91         ncvalue += res->c > res->nc ? res->c : res->nc;
 92         //上司不去的活跃 = 上司不去的活跃度 + 下属去或者不去的最大值,因为上司不去,下属可以去,亦可以不去
 93     }
 94     return new returnType(cvalue, ncvalue);
 95 }
 96 
 97 void Test()
 98 {
 99     vector<vector<int>>data;
100     data = { {1,6},{1,5},{1,4} };
101     cout << getMaxHappy(data) << endl;
102 
103     Node* head = Create(data);
104     returnType* p = calMaxHappy(head);
105     cout << (p->c > p->nc ? p->c : p->nc) << endl;
106 }

转载于:https://www.cnblogs.com/zzw1024/p/11073295.html

猜你喜欢

转载自blog.csdn.net/weixin_34117211/article/details/93462002