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

【题目】

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

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

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

返回最大的活跃值。

举例:

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

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 void process(vector<vector<int>>data, vector<vector<int>>&dp, vector<bool>isVist, int& root)
 8 {
 9     isVist[root] = true;//遍历过
10     dp[root][1] = data[root][1];//获取活跃值
11     for (int i = 0; i < data.size(); ++i)
12     {
13         if (data[i][0] == root && !isVist[i])
14         {
15             process(data, dp, isVist, i);
16             dp[root][1] += dp[i][0];
17             dp[root][0] += dp[i][0] > dp[i][1] ? dp[i][0] : dp[i][1];
18         }
19     }
20 }
21
22
23
24 //使用动态规划解题
25 int getMaxHappy(vector<vector<int>>data)
26 {
27     vector<vector<int>>dp(data.size(), vector<int>(data[0].size(), 0));
28     vector<bool>isVist(data.size(), false);
29     int root = 0;//找到boss
30     for (int i = 0; i < data.size(); ++i)
31         if (data[i][0] == i)//自己是自己的 上司,则此人为boss
32         {
33             root = i;
34             break;
35         }
36     process(data, dp, isVist, root);
37     return dp[root][0] > dp[root][1] ? dp[root][0] : dp[root][1];
38 }
39
40
41 void Test()
42 {
43     vector<vector<int>>data;
44     data = { {1,6},{1,5},{1,4} };
45     cout << getMaxHappy(data) << endl;
46 }

原文地址:https://www.cnblogs.com/zzw1024/p/11073295.html

时间: 2024-10-08 03:45:09

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

左神算法进阶班5_1求二叉树中最大搜索子树大小

[题目] 给定一棵二叉树的头节点head,请返回最大搜索二叉子树的大小 [题解] 简化问题,想到该问题的解答应该有几种情形 第一种可能: 最大搜索二叉子树在head的左子树 第二种可能: 最大搜索二叉子树在head的右子树 第三种可能: 最大搜索二叉子树为自己:利用左子树的最大值与右子树的最小值 递归左子树,再递归右子树 信息1:左子树中最大搜索二叉树的大小 信息2:右子树中最大搜索二叉树的大小 信息3:左子树最大搜索二叉树的头结点 信息4:右子树最大搜索二叉树的头结点 信息5:左子树上的最大值

左神算法进阶班1_5BFPRT算法

在无序数组中找到第k大的数1)分组,每N个数一组,(一般5个一组)2)每组分别进行排序,组间不排序3)将每个组的中位数拿出来,若偶数,则拿上 / 下中位数, 成立一个一个新数组.4)新数组递归调用BFPRT,则拿到整体的中位数num5)以num来划分整体数组,小于在左,大于在右边,使用[荷兰国旗方法]6)然后根据左右数组的规模,来确定进一步选择左右哪一部分:7)然后选择好后,继续 一:背景介绍在一大堆数中求其前k大或前k小的问题,简称TOP - K问题.而目前解决TOP - K问题最有效的算法即

左神算法进阶班1_1添加最少字符得到原字符N次

Problem: 给定一个字符串str1,只能往str1的后面添加字符变成str2. 要求1:str2必须包含两个str1,两个str1可以有重合,但是不能以同一个位置开头. 要求2:str2尽量短最终返回str2 举例: str1 = 123,str2 = 123123 时,包含两个str1,且不以相同位置开头,且str2最短. str1 = 123123,str2 = 123123123 时,包含两个str1,且不以相同位置开头,且str2最短. str1 = 111,str2 = 1111

左神算法进阶班3_1构造数组的MaxTree

题目 一个数组的MaxTree定义: 数组必须没有重复元素 MaxTree是一棵二叉树,数组的每一个值对应一个二叉树节点 包括MaxTree树在内且在其中的每一棵子树上,值最大的节点都是树的头 给定一个没有重复元素的数组arr,写出生成这个数组的MaxTree的函数,要求如果数组长度为N,则时间负责度为O(N).额外空间负责度为O(N). 实现思路 将数组按照大根堆进行排序 然后直接按照大根堆进行构造一颗二叉树即可. 使用单调栈 通过使用单调栈,将数组中中所有数的左右比他大的数记录下来 当某个数

左神算法进阶班6_1LFU缓存实现

[题目] LFU也是一个著名的缓存算法,自行了解之后实现LFU中的set 和 get 要求:两个方法的时间复杂度都为O(1) [题解] LFU算法与LRU算法很像 但LRU是最新使用的排在使用频率最前面,也就是LRU是通过使用时间进行排序, 使用时间越新,其使用频率越高,而使用时间越久,其使用频率越低,即当空间满时,被删除的概率最大 而LFU是根据使用次数来算使用频率的,使用次数越多,其使用频率越高,使用次数越少,使用频率越低,当空间满时越容易被删除 同样,使用hash_map表和双向链表进行存

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

Problem: 复制含有随机指针节点的链表 [题目] 一种特殊的链表节点类描述如下: public class Node { public int value; public Node next; public Node rand; public Node(int data) { this.value = data; } } Node类中的value是节点值,next指针和正常单链表中next指针的意义 一 样,都指向下一个节点,rand指针是Node类中新增的指针,这个指 针可 能指向链表中

【左神算法课】子数组最大差值小于某阈值,求满足条件的子数组个数

题目描述: 解法思路: 本题其实是滑动窗口的变形.主体思路为: 1.从第一个元素开始依次向后遍历,同时维护两个窗口(由于要同时操作窗口的头部和尾部,故采用双端队列): 最大值窗口(递减),头部永远存最大值 最小值窗口(递增),头部永远存最小值 2.比较两个窗口的头部元素差值,若差值大于阈值,即可跳出内循环. 3.跳出内循环后,检查头部元素是否过期,若过期,则清除. 复杂度: 时间复杂度:O(n),注意虽然是两层循环,但元素只从滑动窗口尾部进,从头部清除,只是顺序扫描了一遍. 空间复杂度:O(n)

左神算法第八节课:介绍递归和动态规划(汉诺塔问题;打印字符串的全部子序列含空;打印字符串的全排列,无重复排列;母牛数量;递归栈;数组的最小路径和;数组累加和问题,一定条件下最大值问题(01背包))

暴力递归: 1,把问题转化为规模缩小了的同类问题的子问题 2,有明确的不需要继续进行递归的条件(base case) 3,有当得到了子问题的结果之后的决策过程 4,不记录每一个子问题的解 动态规划 1,从暴力递归中来 2,将每一个子问题的解记录下来,避免重复计算 3,把暴力递归的过程,抽象成了状态表达 4,并且存在化简状态表达,使其更加简洁的可能 一:递归 1. 汉诺塔问题 汉诺塔问题(不能大压小,只能小压大),打印n层汉诺塔从最左边移动到最右边的全部过程. 左中右另称为 from.to.hel

左神算法书籍《程序员代码面试指南》——1_06用栈来求解汉诺塔问题

[问题] 汉诺塔问题比较经典,这里修改一下游戏规则:现在限制不能从最左侧的塔直接移动到最右侧,也不能从最右侧直接移动到最左侧,而是必须经过中间.求当塔有N层的时候,打印最优移动过程和最优移动总步数.例如,当塔数为两层时,最上层的塔记为1,最下层的塔记为2,则打印:Move 1 from left to mid Move 1 from mid to right Move 2 from left to midMove 1 from right to mid Move 1 from mid to le