如何找到M的最小值?

时间:2015-06-04 10:07:18

标签: algorithm

我正试图解决这个问题:

  

你有N个亲戚。你会和ith亲戚谈谈确切的Ti   分钟。每分钟花费1美元。谈话结束后   他们将在您的手机中添加Xi美元充值。最初,你   在你的手机上有M美元的余额。

     

找到你最初必须拥有的M的最小值   电话,这样在任何通话期间都不会失去平衡   (遇到负余额)。

     

注意:您可以按任何顺序致电亲戚。每个亲戚都会   只打了一次。

输入:

N
T1  X1
T2  X2

2
1 1 
2 1

输出:

2

起初这对我来说很容易,但我无法找到确切的解决方案。

我最初的想法:

  

Xi > Ti我们没有问题,因为它不会减少我们的初始值   平衡。我们需要处理将要运行的情况   损失,即Ti > Xi。   但我无法表达会导致最小化的表达   初始值。

在处理此问题时需要指导以找到最佳解决方案。

2 个答案:

答案 0 :(得分:1)

<强>更新: -

二元搜索方法似乎导致了错误的结果(正如   用户greybeard在评论中提供的测试用例。

所以,这是另一种方法。我们维持通话费用之间的差异   和充值金额。

然后我们维护两个数组/向量。   如果我们的充值金额严格大于电话费,我们就把   第一个数组中的调用,否则我们将它放在第二个数组中。

然后我们可以根据成本和第二个数组对第一个数组进行排序   根据充值金额。然后我们通过添加来更新diff   我们的费用高于充值的电话充电量最少

然后我们可以迭代我们的第一个数组并更新我们的最大值   要求,每次通话的要求和当前的平衡。最后,我们的答案   将是最大要求与我们维持的差异之间的最大值。

示例: -

   N = 2
   T1 = 1 R1 = 1
   T2 = 2 R2 = 1

我们的第一个数组不包含任何内容,因为所有调用的成本都高于    或等于充值金额。所以,我们将两个调用放在第二个数组中    在对数组进行排序之前,diff会更新为2。然后,我们添加min    充电,我们可以从我们的差异调用(即1)得到。现在,差异是站立的    在3.然后,由于我们的第一个数组不包含任何元素,我们的答案等于    差异即3.

时间复杂度: - O(nlogn)

工作示例: -

#include<bits/stdc++.h>
using namespace std;
#define MAXN 100007

int n,diff;
vector<pair<int,int> > v1,v2;

int main(){
    diff = 0;
    cin>>n;
    for(int i=0;i<n;i++){
    int cost,recharge;
    cin>>cost>>recharge;
    if(recharge > cost){
       v1.push_back(make_pair(cost,recharge));
    }else{
       v2.push_back(make_pair(recharge,cost));
    }
    diff += (cost-recharge);
   }
   sort(v1.begin(), v1.end());
   sort(v2.begin(), v2.end());
   if(v2.size() > 0)diff += v2[0].first;
   int max_req = diff, req = 0,cur = 0;
   for(int i=0; i<v1.size(); i++){
      req = v1[i].first - cur;
      max_req = max(max_req, req);
      cur += v1[i].second-v1[i].first;
   }
   cout<<max(max_req,diff)<<endl;
   return 0;
}

答案 1 :(得分:1)

(这是一个维基帖:您被邀请进行编辑,并且在没有主持人的情况下不需要太多声誉。)

高效工作意味着完成手头的任务,而不需要过多的努力。方面在这里:

  • OP要求guidance in approaching this problem to find optimal solution - 以获得解决方案(正如此entirely similar, older question所做的那样)。
  • 问题陈述要求the minimum value of M - 是最佳的通话顺序或如何找到它。

要查找最初需要的最低余额,请对亲属/(T,X) - 对/呼叫进行分类(可能的命令具有含义,如果不是针对所述问题)

  1. T&lt; X使X-T更多用于跟随呼叫。按成本增加的顺序 开始假设初始余额为1.对于每次通话,如果您能负担得起,减去其成本,添加退款并完成会计处理。如果你还没有负担(还),请将其置于保持/后烧/优先级队列中。在&#34;奖励电话&#34;结束时,依次删除队列中的每个队长,考虑到初始平衡的必要增加。
    此部分以最高余额结束,但
  2. T = X对任何其他通话没有影响。只需按照任何顺序进行最高平衡 整个序列所需的最高余额不能低于任何一次通话的费用,包括这些费用。
  3. T&gt; X为后续呼叫留下较少的T-X。按顺序减少退款。
    (这可以像任何电话一样,在退款之前达到零余额。 由于呼叫顺序不会改变总成本,因此需要最少初始余额的那些将是产生最低最终成本的那些。对于此类别所要求的中间余额,请不要忘记最低退款。)
  4. 结合所有类别的要求 请记住指南的请求。