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