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越小越好)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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; } };
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 ", 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]; } };