leetcode 1029 两地调度(贪心)
题目描述:
公司计划面试 2N 人。第 i 人飞往 A 市的费用为 costs[i][0],飞往 B 市的费用为 costs[i][1]。返回将每个人都飞到某座城市的最低费用,要求每个城市都有 N 人抵达。
题解:
个人思路:为了近可能的降低费用,我们应该优先安排飞往A、B两市费用差距最大的去费用较小的市,以此来降低整体费用。这么做的话对差值的绝对值排序然后贪心的选就可以了。代码如下:
class Solution { public: static int cmp(vector<int> a,vector<int> b) { return abs(a[0]-a[1]) > abs(b[0]-b[1]); } int twoCitySchedCost(vector<vector<int>>& costs) { sort(costs.begin(),costs.end(),cmp); int ans = 0; int cnt0 = 0; int cnt1 = 0; int N = costs.size(); for(auto &cost:costs) { if(cnt0 >= N/2) { ans += cost[1]; continue; } if(cnt1 >= N/2) { ans += cost[0]; continue; } if(cost[0] < cost[1]) { ans += cost[0]; cnt0++; } else { ans += cost[1]; cnt1++; } } return ans; } };
官方思路:这样看这个问题,首先将这$2N$个人全部安排飞往$B$市,再选出$N$个人改变他们的行程,让他们飞往$A$市。如果选择改变一个人的行程,那么公司会额外付出$price_A - price_B$的费用,这个费用可正可负。因此最优的方案是选出$price_A - price_B$最下的$N$个人飞往$A$市。代码如下:
class Solution { public: int twoCitySchedCost(vector<vector<int>>& costs) { // Sort by a gain which company has // by sending a person to city A and not to city B sort(begin(costs), end(costs), [](const vector<int> &o1, const vector<int> &o2) { return (o1[0] - o1[1] < o2[0] - o2[1]); }); int total = 0; int n = costs.size() / 2; // To optimize the company expenses, // send the first n persons to the city A // and the others to the city B for (int i = 0; i < n; ++i) total += costs[i][0] + costs[i + n][1]; return total; } };