过桥时间最短的算法实现(TopCoder)

该博客探讨了一个晚上过桥的问题,每次只能2人过桥并需要一盏灯。作者提出了一种效率较低的解决方法,通过排序和迭代器进行计算。文章最后展示了一种使用多重集合优化的算法,以最小化过桥总时间,并给出了具体实现和示例测试。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题描述:

一群人晚上过桥,每次只能过2个人,并且需要一盏灯。 每个人过桥时间不同。计算最短时间

给出是过桥时间如{1,2,5,10},计算出最小时间17

首先 1,2 过去 时间 2    

         1       回来   时间 1 

       5,10 过去 时间 10

       2        回来   时间 2

   1,2   过去    时间  2

总共 17

未过一方:小   大   小   大。。。。。

过去一方       小   小    小。。。。

我自己的是按照这个流程作:但是感觉效率很低,大家有什么好的思路或者这个思路的效率高的方法;

 #include <vector>
#include <algorithm>
#include <iostream>
#include <set>
#include <iterator>
using namespace std;

class BridgeCrossing
{
public:
 int minTime(vector <int> times)
 {

  //if (times.size() <= 1) {
  // return times[0];
  //}
  //int persons = times.size();
  //vector<int> left(times.begin(), times.end());
  //vector<int> right(persons, 0);
  //int mintime = 0;
  //int lp = persons;
  //int tmp = 0;

  //sort(left.begin(), left.end());
  //while (lp > 0) {
  // right[0] = left[0]; lp--;
  // right[1] = left[1]; lp--;
  // mintime += left[1];
  // if (lp <= 0)
  //  return mintime;

  // mintime += right[0]; lp++;

  // right[persons - (2*tmp + 1)] = left[persons - (2*tmp + 1)]; lp--;
  // right[persons - (2*tmp + 2)] = left[persons - (2*tmp + 2)]; lp--;
  // mintime += left[persons - (2*tmp + 1)];
  // if (lp <= 0)
  //  return mintime;

  // mintime += right[1]; lp++;
  // tmp++;
  //}
 
  if(times.size()==1)
   return times[0];
  multiset<int> left(times.begin(),times.end());
  multiset<int> right;
  int mintime=0;
  unsigned persons = left.size();
 // cout<<"end"<<endl;
 // copy(left.begin(),left.end(),ostream_iterator<int>(cout," "));
 
  cout<<endl;
  while(persons>0)
  {
   int time=0;
   multiset<int>::iterator iter = left.begin();
   //左边2个
   //第一个
   time=*iter;
   iter=left.erase(iter);persons--;
   right.insert(time);
   //第二个
   time=*iter;
   iter=left.erase(iter);persons-- ;
   mintime+=time;
   right.insert(time);

   if(persons<=0)
    return mintime;
   //从右边过来一个最小的
   iter = right.begin();
   time=*iter;
   iter=right.erase(iter);
   mintime+=time;
   left.insert(time);persons++;

   //左边两个最大的
   iter = left.end();
    //第一个
   time = *(--iter);
   mintime+=time;
   iter=left.erase(iter);
   right.insert(time);persons--;
   //第二个
   iter--;
   time= *iter;
   iter=left.erase(iter);
   right.insert(time);persons--;
   if(persons<=0)
    return mintime;

    //从右边过来一个最小的
   iter = right.begin();
   time=*iter;
   iter=right.erase(iter);
   mintime+=time;
   left.insert(time);persons++;
   
  }

  return mintime;
 }
};

int _tmain(int argc, _TCHAR* argv[])
{
 int a[] = { 1, 2, 3, 50, 99, 100 };
 vector<int> arg(a, a + sizeof(a)/sizeof(a[0]));

 BridgeCrossing bc;
 cout << bc.minTime(arg) << endl;

 return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值