2020-07-25

857. 雇佣 K 名工人的最低成本

题解:

对于每一个工人i,其薪质比为wage[i] / quality[i],
则对其余工人j,应该支付price[j] = wage[i] / quality[i] * quality[j],
而每一个工人都需要price[j]>=wage[j], 
即 wage[i] / quality[i] >= wage[j] / quality[j]
所以首先按照wage[i] / quality[i] 从小到大排序, 保证选到 i 时,其余的工人都能够得到最低工资。

如果已经有K人了,再加人的时候,我们如果要筛选人的话,肯定是去掉quality最大的(因为薪质比按照当前的工人来的,所以肯定
quality越小越好)
class Solution {
public:
    
    double mincostToHireWorkers(vector<int>& quality, vector<int>& wage, int K) {
        vector<pair<double,int>> worker;
        for(int i=0;i<quality.size();i++){
            worker.push_back({wage[i]*1.0/quality[i], quality[i]});
        }
        sort(worker.begin(), worker.end()); 
        priority_queue <int> q;
        double ans = 1e9;
        int qualitysum = 0;
        for(int i=0;i<worker.size();i++){
            q.push(worker[i].second);
            qualitysum+=worker[i].second;
            if(q.size()==K){
                ans = min(ans, qualitysum*worker[i].first);
                qualitysum -= q.top();
                q.pop();
            }
        }
        return ans;
    }
};
View Code

410. 分割数组的最大值

题解: 经典最大值最小问题, 二分找即可

class Solution {
public:
    int splitArray(vector<int>& nums, int m) {
        long long l = nums[0], r = 0;
        for(int i=0;i<nums.size();i++) r+=nums[i], l=max(1ll*nums[i],l);
        while(l<r){
            long long mid = l + (r-l)/2;
            long long now = 0;
            int block=1;
            for(int i=0;i<nums.size();i++){
                now+=nums[i];
                if(now>mid){
                    now = nums[i];
                    block++;
                }
            }
            if(block >m) l = mid+1; /// 分出来块数比m多,证明阈值小了
            else r = mid; 
        }
        return l;
    }
};

最大值最小模板:

while(l<r){
    int mid = (l+r)>>1;
    if(ok) r = mid;
    else l = mid+1;   
}

最小值最大模板:

while(l<r){
    int mid = l + (r-l+1)/2;
    if(ok) l  = mid;
    else r = mid-1;
}

 

1161. 最大层内元素和

/**
 * 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:
    int maxLevelSum(TreeNode* root) {
        queue <TreeNode*> q;
        int maxx = 0, ans = 1;
        int layer = 0;
        q.push(root);
        while(q.size()){
            int n = q.size();
            int tmp = 0;
            layer+=1;
            for(int i=0;i<n;i++){
                TreeNode * now = q.front(); q.pop();
                tmp += now->val;
                if(now->left) q.push(now->left);
                if(now->right) q.push(now->right);
            }
            //printf("%d %d\n", tmp, maxx);
            if(tmp > maxx) {maxx = tmp, ans = layer;} 
        }
        return ans;
    }
};

 

337. 打家劫舍 III

和线性数组一样,每个叶子只有两种选择,取/不取,记忆化+DFS即可。

/**
 * 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:
    map <TreeNode * , int>  mp;
    int rob(TreeNode* root) {
        if(!root) return 0;
        if(mp[root]) return mp[root];
        int _do = root->val;
        if(root->left) _do += rob(root->left->left)+rob(root->left->right);
        if(root->right) _do += rob(root->right->left)+rob(root->right->right);
        int un_do = rob(root->left) + rob(root->right);
        mp[root] = max(_do, un_do);
        return mp[root];
    }
};

 

posted @ 2020-07-25 12:02  樱花庄的龙之介大人  阅读(165)  评论(0编辑  收藏  举报