题目大意
有2N个人,现将这2N个人送到A, B两个城市,每个人送到不同城市的代价为costs。计算将这2N个人送到不同城市的最小代价,要求每个城市刚好送N个人。
思路
乍一看有点像动态规划,但是思考后发现有一定的贪心策略在里面。实际上,去A的代价与去B的代价 cost[a] - cost[b]
代表让一个人去B能够节约的钱,反之,cost[b] - cost[a]
代表一个人去A能够节约的钱。而这两组数互为相反数。所以只需计算一组然后选前N个去A,后N个去B。
优化,计算所有的差值之后,只要选前N个小的就行,所以可以用nth_element
。
我的方法
先把每个人的代价中最小的加起来,得到总代价sum
,当然这个时候去A的人数acount
与去B的人数bcount
不相等。不妨假设acount > bcount
,则需要将去A的一些人安排到B。这个时候使用上述同样的方法,将去A的人数中cost[b] - cost[a]
最小的几个人安排到B即可。
代码
class Solution {
public:
int twoCitySchedCost(vector<vector<int>>& costs) {
const int n = costs.size() / 2;
priority_queue<int, vector<int>, greater<int>> q;
int acount = 0, bcount = 0, sum = 0;
for (const auto &tmpvec: costs) {
sum += min(tmpvec[0], tmpvec[1]);
if (tmpvec[0] < tmpvec[1]) acount++;
else bcount++;
}
for (const auto &tmpvec: costs){
if (acount > bcount && tmpvec[0] < tmpvec[1])
q.push(tmpvec[1] - tmpvec[0]);
else if (acount < bcount && tmpvec[1] <= tmpvec[0])
q.push(tmpvec[0] - tmpvec[1]);
}
for (int i = 0; i < max(acount, bcount) - n; i++) {
sum += q.top();
q.pop();
}
return sum;
}
};
总结
比较巧妙的贪心题目。