47-过河问题
内存限制:64MB
时间限制:1000ms
Special Judge: No
accepted:2
submit:5
题目描述:
在漆黑的夜里,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、有两种走的方法
①、由耗时最短的带耗时最长的
②、用耗时最长的带耗时第二长的(当然,我们需要一个耗时最短的两个人去带电灯回来)
核心代码:
1 int a = A[n-1] + A[n-2] + A[0] + A[0]; 2 int b = A[n-1] + A[1] + A[1] + A[0]; 3 int c = min(a, b);
C/C++代码实现(AC):
1 #include <iostream> 2 #include <algorithm> 3 #include <cstring> 4 #include <cstdio> 5 #include <cmath> 6 #include <stack> 7 #include <map> 8 #include <queue> 9 #include <set> 10 11 using namespace std; 12 const int MAXN = 1010; 13 14 int main() 15 { 16 int t; 17 scanf("%d", &t); 18 while(t --) 19 { 20 int n, A[MAXN]; 21 scanf("%d", &n); 22 for(int i = 0; i < n; ++ i) 23 scanf("%d", &A[i]); 24 25 sort(A, A+n, less<int>()); 26 if (n <= 2) 27 { 28 printf("%d ", A[n-1]); 29 continue; 30 } 31 if (n == 3) 32 { 33 printf("%d ", A[0] + A[1] + A[2]); 34 continue; 35 } 36 int cnt = A[1]; 37 while(n > 3) 38 { 39 int a = A[n-1] + A[n-2] + A[0] + A[0]; 40 // 最后两位耗时多的全部让第一号来送 41 int b = A[n-1] + A[1] + A[1] + A[0]; 42 // 让最前面两个先走,再让第二个带灯回来,让后两个一起走,最后再让最先过来的第一号带灯回来 43 44 int c = min (a, b); // 选取耗时最短的策略 45 cnt += c; 46 n -= 2; 47 if (n == 3) 48 cnt += A[2] + A[0]; 49 } 50 printf("%d ", cnt); 51 } 52 return 0; 53 }