【题目】

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

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

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

返回最大的活跃值。

举例:

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

matrix =

{

1,6

1,5

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

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

  1. 左神算法中级班第三课[C++代码]

    左神算法中级班第三课[C++代码] 第一题:流水线打包问题[阿里原题] 代码 第二题 代码 第三题:打印螺旋矩阵 代码 第四题 代码 第五题:判读aim是否在矩阵中 代码 第七题:topK问题 代码 ...

  2. 0206.BFPRT在一大堆数中求其前k大或前k小的问题,简称TOP-K问题(左神算法基础班源码)

    package basic_class_02;/*** * 在一大堆数中求其前k大或前k小的问题,简称TOP-K问题.* 而目前解决TOP-K问题最有效的算法即是BFPRT算法**/ public c ...

  3. 13.在一个数组中,每一个数左边比当前数小的数累加起来,叫做这个数组的小和。求一个数组的小和。(左神算法基础班源码)

    package basic_class_01; /*** *小和问题在一个数组中,每一个数左边比当前数小的数累加起来,叫做这个数组的小和.求一个数组的小和.例子:[1,3,4,2,5]1左边比1小的数 ...

  4. 【搞定左神算法初级班】第4节:二叉树及相关常见面试题

    目 录: 题目1:实现二叉树的先序.中序.后序遍历[递归方式和非递归方式] 题目2:在二叉树中找到一个节点的后继节点 题目3:介绍二叉树的序列化和反序列化 题目4:折纸问题 题目5:判断一棵二叉树是否 ...

  5. 左神算法初级班笔记4:二叉树

    文章目录 01 | 实现二叉树的先序.中序.后序遍历,包括递归方式和非递归 方式 1.递归版本: 2. 非递归版本: 02 | 在二叉树中找到一个节点的后继节点 03 | 介绍二叉树的序列化和反序列化 ...

  6. 《左神算法初级班》第四节课:二叉树结构

    目录: 1)二叉树结构 2)二叉树的递归与非递归遍历 3)打印二叉树 4)判断搜索二叉树 5)判断完全二叉树 6)判断平衡二叉树 7)折纸问题 8)二叉树节点的前驱节点与后继节点 9)二叉树的序列化和 ...

  7. 左神算法基础班3_13深度拷贝含有随机指针的链表

    Problem: 复制含有随机指针节点的链表 [题目] 一种特殊的链表节点类描述如下: public class Node { public int value; public Node next; ...

  8. 左神算法基础班4_4_3在二叉树中找到一个节点的后继节点

    Problem: 在二叉树中找到一个节点的后继节点 [题目] 现在有一种新的二叉树节点类型如下: public class Node { public int value; public Node l ...

  9. 左神算法(一)下修改版

    序言: 此篇内容紧跟在左神算法(一)上修改版之后. 左神算法(一)上修改版 左神算法(一)下修改版 左神算法(二) 七.二叉树的基本算法 1.二叉树 2.二叉树的先序.中序.后序遍历 先序:任何子树的 ...

最新文章

  1. .NET Core 2.0 Preview 2为开发人员带来改进
  2. Understand one Simple Factory Pattern
  3. 温州大学《机器学习》课程代码(四)朴素贝叶斯
  4. JS replace 回调
  5. atitit.it企业管理 项目管理 中的 授权机制 的来源 君权神授 的一定合理性
  6. STM32----摸石头过河系列(五)
  7. Game(HDU-6669)
  8. box head上身旋转问题
  9. c语言怎样存放学生信息,C语言共用体存放学生信息
  10. AutoCAD VBA创建椭圆和样条曲线
  11. 量子纠缠,如何理解不确定性
  12. spring纯注解+libreoffice
  13. 移动机器人路径规划:人工势场法
  14. 各省份国内、入境旅游人数 (2007-2018年)
  15. linux 没有dll文件,求助 hai.dll文件丢失 在线等
  16. 曙光服务器面板显示感叹号,磁盘阵列和磁带库面板感叹号灯橙色
  17. 2018.10.27 bzoj1984: 月下“毛景树”(树链剖分)
  18. C++中 =defaule 和 =delete 使用
  19. 内网穿透 永久免费 简单实现外网访问内网SpringBoot
  20. 移植uCOS-II到STM32F103平台攻略

热门文章

  1. SpringMVC项目中,jsp文件无法显示从Controller中传递过来的ModelAndView的模型数据
  2. oracle export命令使用浅解,Oracle Export命令使用浅解
  3. Java的垃圾回机机制(见过讲得最清楚的)
  4. Redis数据类型使用场景及有序集合SortedSet底层实现详解
  5. Paxos Made Simple
  6. 交叉编译Python-2.7.13到ARM(aarch32)平台
  7. [HDOJ1897]继续畅通工程
  8. 光棍节的快乐 NYOJ 451
  9. PHP版本选择讲解:VC6与VC9,Thread Safe与None-Thread Safe等的选择
  10. 判断循环双链表是否对称