【思维】树形dp+构造——leetcode二叉树任务调度

这题实际上是要构造出一种最优的调度策略吧。。

有一个二叉树形式的任务依赖结构,我们有两个 CPU 核,这两个核可以同时执行不同的任务,问执行完所有任务的最小时间,也即是希望两个 CPU 核的并行时间尽可能大

先对题目给定的条件进行分析:

  1.对于子树u来说,结点u是必须串行的(u下的结点都依赖于u)

  2.子树u的执行策略必定是:在u上串行,并行一段时间,最后执行到一条链的时候必须串行

  3.设左儿子lson执行总时间>右儿子rson,那么有一个最优的策略:尽可能的让lson和rson并行最大时间

    那么我们在lson上减去rson的运行时间(这部分可以左右并行,且优先减去lson上不能并行的那部分时间),lson剩下的时间尽量并行跑即可

所以结点u需要维护两个量:sum, parallel,sum表示子树u下运行总时间,parallel表示子树u下最大的并行时间

  设a,b,c,d分别为lson的sum,parallel, rson的sum,parallel,要求u的sum,parallel  

  如果a-2b<=c,说明lson和rson可以一直并行,sum[u]=a+c+val[u],parallel[u]=a+c>>1

  反之a-2b>c,说明lson里有a-2b-c的时间只能串行,sum[u]=a+c+val[u],parallel[u]=c+b

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:

    pair<int,double> dfs(TreeNode* root){
        if(!root)return {0,0.0};
        auto lson=dfs(root->left);
        auto rson=dfs(root->right);
        if(lson.first<rson.first)
            swap(lson,rson);

        auto a=lson.first,c=rson.first;
        auto b=lson.second,d=rson.second;
        if(a-2*b<=c)
            return {a+c+root->val,(a+c)*0.5};
        else 
            return {a+c+root->val,b+c};
        
    }

    double minimalExecTime(TreeNode* root) {
        auto p=dfs(root);
        return p.first-p.second;
    }
};

 

posted on 2020-06-03 09:42  zsben  阅读(328)  评论(0编辑  收藏  举报

导航