LeetCode刷题之——1029. Two City Scheduling (双城面试2N人费用最小问题)

1029. Two City Scheduling (双城面试2N人费用最小问题)

There are 2N people a company is planning to interview. The cost of flying the i-th person to city A is costs[i][0], and the cost of flying the i-th person to city B is costs[i][1].

Return the minimum cost to fly every person to a city such that exactly N people arrive in each city.

Example 1:

Input: [[10,20],[30,200],[400,50],[30,20]]
Output: 110
Explanation: 
The first person goes to city A for a cost of 10.
The second person goes to city A for a cost of 30.
The third person goes to city B for a cost of 50.
The fourth person goes to city B for a cost of 20.

The total minimum cost is 10 + 30 + 50 + 20 = 110 to have half the people interviewing in each city.

Note:

  1. 1 <= costs.length <= 100
  2. It is guaranteed that costs.length is even.
  3. 1 <= costs[i][0], costs[i][1] <= 1000

以上是原题描述。

现在来说一下我的算法:

  1. 从每个数对中选择较小的那个,选完后分成了a、b两列
  2. 看a和b谁更多,计算出多的一方需要补偿给对方几个(n)
  3. 计算多的一列中的数字在原来数对中的差值,选择前n个差值最小的数对,进行替换

比如上面的例子,第一步后,a列:259;b列:54,667,139,118,469.

第二步:a列1个,b列5个,相差4个,b需要补给a列2个。

第三步:计算出新的差值列:394,259,45,722,108. 发现最小的2个是45和108,对应的是184替换139,577替换469.(见下图)

 最终我们选择的数字是:259,54,667,184,139,118,577.

和为1859.

代码:

  1 class Solution {
  2 public:
  3     int twoCitySchedCost(vector<vector<int>>& costs) {
  4         int result=0;
  5         vector<vector<int>> a;//左列
  6         vector<vector<int>> b;//右列
  7         vector<int> c;          //辅助
  8         vector<vector<int>> d;//差值
  9         int diff;
 10         
 11         //初始分选,每个数对选最小的那个
 12         for (auto iter = costs.begin(); iter != costs.end(); iter++)
 13         {
 14          if((*iter)[0]>(*iter)[1]) {
 15              c.push_back((*iter)[1]);
 16              c.push_back(iter-costs.begin());//返回原始数组的第一维下标
 17              b.push_back(c);
 18          }
 19             else{
 20                 c.push_back((*iter)[0]);
 21                 c.push_back(iter-costs.begin());//返回原始数组的第一维下标
 22                 a.push_back(c);
 23             }
 24             c.clear();
 25         }
 26         
 27         diff=a.size()-b.size();//a比b多几个
 28         if(diff==0){
 29               for (auto iter = a.begin(); iter != a.end(); iter++)
 30                 result+=(*iter)[0] ;
 31      
 32               for (auto iter = b.begin(); iter != b.end(); iter++)
 33                 result+=(*iter)[0] ;
 34         }
 35         else if(diff > 0){//a>b
 36             diff = diff/2;//2N人一定能整除
 37             for (auto iter = a.begin(); iter != a.end(); iter++)
 38             {
 39                 int index=(*iter)[1];
 40                 c.push_back(abs(costs[index][0]-costs[index][1]));
 41                 c.push_back(index);
 42                 d.push_back(c);
 43                 c.clear();
 44             } 
 45             for (auto iter = b.begin(); iter != b.end(); iter++)
 46                 result+=(*iter)[0] ;
 47             while(diff-->0){
 48                 int index = smallest(d);//注意这里
 49                  for (auto iter = a.begin(); iter != a.end(); iter++)
 50                 {
 51                     if((*iter)[1]==index)
 52                         (*iter)[0]=costs[(*iter)[1]][1];//注意第二个下标是1
 53                 }
 54             }
 55             for (auto iter = a.begin(); iter != a.end(); iter++)
 56                 result+=(*iter)[0] ;
 57         }
 58         else{//diff<0
 59             //a<b
 60             diff=0-diff;
 61             diff = diff/2;
 62             for (auto iter = b.begin(); iter != b.end(); iter++)
 63             {
 64                 int index=(*iter)[1];
 65                 c.push_back(abs(costs[index][0]-costs[index][1]));
 66                 c.push_back(index);//返回原始数组的第一维下标
 67                 d.push_back(c);
 68                 c.clear();
 69             } 
 70             for (auto iter = a.begin(); iter != a.end(); iter++)
 71                 result+=(*iter)[0] ;
 72             while(diff>0){
 73                 int index = smallest(d);//注意这里
 74                  for (auto iter = b.begin(); iter != b.end(); iter++)
 75             {
 76                     if((*iter)[1]==index){
 77                         (*iter)[0]=costs[(*iter)[1]][0];//注意第二个下标是0
 78                         diff--;
 79                     }
 80                         
 81                     
 82             }
 83             }
 84            
 85             for (auto iter = b.begin(); iter !=b.end(); iter++)
 86                 result+=(*iter)[0] ;
 87         }
 88         
 89         return result;
 90     }
 91     
 92     int  smallest(vector<vector<int>>& hahaha){
 93         vector<int> c;
 94         for (auto iter = hahaha.begin(); iter != hahaha.end(); iter++)
 95             c.push_back((*iter)[0]);
 96         auto smallest=min_element(begin(c),end(c));
 97         int index = hahaha[distance(begin(c),smallest)][1];
 98         hahaha[distance(begin(c),smallest)][0]=1000;
 99         return index;
100     }
101 };

本地测试用的主函数:

1 int main() {
2     Solution* mySo = new Solution();
3     vector<vector<int>> cos = { {259,770},{448,54},{926,667},{184,139},{840,118},{577,469} };
4     cout << mySo->twoCitySchedCost(cos) << endl;
5 }

注:这道题难度是easy·········

  

原文地址:https://www.cnblogs.com/mrlonely2018/p/13273779.html