描述

在漆黑的夜里,N位旅行者来到了一座狭窄而且没有护栏的桥边。如果不借助手电筒的话,大家是无论如何也不敢过桥去的。不幸的是,N个人一共只带了一只手电筒,而桥窄得只够让两个人同时过。如果各自单独过桥的话,N人所需要的时间已知;而如果两人同时过桥,所需要的时间就是走得比较慢的那个人单独行动时所需的时间。问题是,如何设计一个方案,让这N人尽快过桥。 


 

输入 第一行是一个整数T(1<=T<=20)表示测试数据的组数

每组测试数据的第一行是一个整数N(1<=N<=1000)表示共有N个人要过河

每组测试数据的第二行是N个整数Si,表示此人过河所需要花时间。(0<Si<=100) 输出 输出所有人都过河需要用的最少时间 样例输入

1
4
1 2 5 10

样例输出

17
分析:以1 2 5 10和1 5 7 10为例子分析大致思路
一,1 2 5 10.(当最快两个人的速度相差不大时)
1.  先最快的一组过河,然后将该组的最快的人回到原地传递电筒。
2.  将走的最慢的一组过河,然后由第一组剩下的人,将电筒带回。
3.  重复1. 2.步骤
二,1 5 7 10(当最快两个人的速度相差较大时)
思路。最慢和最快的人一起过河,并由最快的人带回电筒。以此重复。
如果该组数据使用一方法。一共是23,而方法二,需要21
总结以上:相当于把最快的一组或一个人当做小车载最慢的一组过河。当把他们慢的组都运完了(没有留下单个的人,那么一共肯定是偶数个人,否则为奇数个)
,再处理最快组合余下的人。
注意:当人小于等于3时,就不需要前面的处理。
这是WA的代码:我还不知道错在哪里。欢迎改正。再下面是正确代码,也是对该代码的优化:


#include<iostream>

#include<algorithm>

using namespace std;

int main()

{

 int repeat;

 cin >> repeat;

 for (int i = 0; i < repeat; i++)

 {

  int datanum;

  cin >> datanum;

  int *ps = new int[datanum];

  //输入各个人的时间

  for (int j = 0; j < datanum; j++)

  {

   cin >> ps[j];

  }

  //排序

  sort(ps, ps + datanum); //sort()默认从小到大排序

  for (int j = 0; j < datanum; j++)

  {

   cout << ps[j] << " ";

  }

  //主要算法

  //datanum的奇数偶数分为两种算法

  int MinTime1 = 0;

  int MinTime2 = 0;

  int MinTime = 0;

  cout << endl;

  if (datanum % 2 == 0&&datanum>1)

  {

   for (int j = datanum - 1; j>1; j-=2)

   {

    MinTime1 = ps[0] + ps[1] + ps[j] + ps[1];

    MinTime2 = ps[j] + ps[j - 1] + 2 * ps[0];

    if (MinTime1 < MinTime2){ MinTime += MinTime1; cout << "1"; }

    else{ MinTime += MinTime2; cout << "2" << MinTime2 << " " << MinTime1 << endl; }

   }

   MinTime += ps[1];

  }

  else if (datanum%2!=0&&datanum>1)

  {

   for (int j = datanum - 1; j>2; j -= 2)

   {

    MinTime1 = ps[0] + ps[1] + ps[j] + ps[1];

    MinTime2 = ps[j] + ps[j - 1] + 2 * ps[0];

    if (MinTime1 < MinTime2){ MinTime += MinTime1; }

    else{ MinTime += MinTime2; }

   }

   MinTime += ps[0] + ps[1] + ps[2];

  }

  else

  {

   MinTime += ps[0];

  }

  cout << MinTime << endl;

  delete[]ps;

  ps = NULL;

 }

 return 0;

}

这是已经通过的代码

#include<iostream>

#include<algorithm>

using namespace std;

int MinTime(int *a, int n);

int main()

{

 int repeat;

 int datanum;

 int time;

 cin >> repeat;

 while (repeat--)

 {

  cin >> datanum;

  int *ps = new int[datanum];

  for (int i = 0; i < datanum;  i++)

  {

   cin >> ps[i];

  }

  time=MinTime(ps, datanum);

  cout << time << endl;

  delete[]ps;

  ps = NULL;

 }

}

int MinTime(int *a, int n)

{

 sort(a, a + n);

 n--;

 int mintime = 0;

 while (n > 2)

 {

  mintime += min(a[0] + a[1] * 2 + a[n], a[0] * 2 + a[n] + a[n - 1]);

  n -= 2;

 }

 if (n == 0){ mintime = a[0]; }

 else if (n == 1){ mintime += a[1]; }

 else { mintime += a[0] + a[1] + a[2]; }

 return mintime;