LeetCode Daily challenge - Two City Scheduling

题目大意

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

总结

比较巧妙的贪心题目。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值