派对的最大快乐值

公司员工可以用树形结构表示,除了老板以外,每个员工都有直属上级,除基层员工外,每个员工都有一个或者多个下级。公司要办party,请返回派对的最大快乐值。

  • 某个员工来了,那他的直接下级不能参加。

  • 派对快乐值是到场的所有员工快乐值的累加。

  • 目标是让派对快乐值最大。

假设有头节点X,假设X的下级员工为A,B,C。,那么分为两种情况: 1. X不参加派对,那么快乐值为 NO_X和max(YES_C, NO_C)、max(YES_C, NO_C)、max(YES_C, NO_C)。 2. X参加派对,那么快乐值为YES_X和NO_A、NO_B、NO_C的快乐值的和。

显然是个递归结构,并且递归的过程需要返回node的YES_node值和NO_node值。(YES_node表示node参加,NO_node表示node不参加)。

use std::{cell::RefCell, rc::Rc};
struct Employ {
    happy: i32, // 快乐值
    subordinates: Vec<EmployRef>, // 下级员工
}

type EmployRef = Rc<RefCell<Employ>>;

impl Employ {
    fn new(happy: i32) -> Rc<RefCell<Employ>> {
        Rc::new(RefCell::new(Employ { happy, subordinates: vec![] }))
    }
    fn get_happy(&self) -> i32 {
        self.happy
    }

    fn add_subordinates<I>(&mut self, subordinates: I)
    where
        I: IntoIterator<Item = EmployRef>,
    {
        for subordinate in subordinates {
            self.subordinates.push(subordinate);
        }
    }

    fn get_subordinates(&self) -> &Vec<EmployRef> {
        &self.subordinates
    }
}

struct ReturnData {
    yes_head_max: i32,
    no_head_max: i32,
}

fn get_max_happy(employ: EmployRef) -> ReturnData {
    let mut yes = employ.borrow().get_happy();
    let mut no = 0;

    if employ.borrow().get_subordinates().is_empty() {
        return ReturnData {
            yes_head_max: yes,
            no_head_max: no,
        };
    } else {
        for sub in employ.borrow().get_subordinates() {
            let data = get_max_happy(sub.clone());
            yes += data.no_head_max;
            no += data.yes_head_max.max(data.no_head_max);
        }

        return ReturnData {
            yes_head_max: yes,
            no_head_max: no,
        };
    }
}

fn max_happy(employ: EmployRef) -> i32 {
    let data = get_max_happy(employ);
    return data.yes_head_max.max(data.no_head_max);
}

#[test]
fn test() {
    let employ = Employ::new(10);
    let employ1 = Employ::new(20);
    let employ2 = Employ::new(30);
    let employ3 = Employ::new(40);

    let employ_1_1 = Employ::new(50);
    let employ_1_2 = Employ::new(60);

    employ.borrow_mut().add_subordinates(vec![employ1.clone(), employ2.clone(), employ3.clone()]);
    employ1.borrow_mut().add_subordinates(vec![employ_1_1.clone(), employ_1_2.clone()]);

    assert_eq!(max_happy(employ), 180);
}

评论