1. 程式人生 > 實用技巧 >2020-07-25

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;
}