描述
在漆黑的夜里,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;
}