Given the two fastest people as f1 and f2, f1 < f2, and the two slowest people as s1 and s2, s1 < s2. We want to use the two fastest people to bring the two slowest people to cross the bridge. There are two efficient ways of doing this:
1) f1, f2 go --> f1 back --> s1, s2 go --> f2 back: time1 = f2 + f1 + s2 + f2
2) f1, s1 go --> f1 back --> f1, s2 go --> f1 back: time2 = s1 + f1 + s2 + f1
Then, we can compare time1 with time2 to choose the better way.
Code:
- /*************************************************************************
- * Copyright (C) 2008 by liukaipeng *
- * liukaipeng at gmail dot com *
- *************************************************************************/
- /* @JUDGE_ID 00000 10037 C++ "Bridge" */
- #include <algorithm>
- #include <deque>
- #include <fstream>
- #include <iostream>
- #include <list>
- #include <map>
- #include <queue>
- #include <set>
- #include <stack>
- #include <string>
- #include <vector>
- using namespace std;
- int const timecount = 1000;
- void cross_bridge(int *times, int ntimes, int strategy[][2])
- {
- sort(times, times + ntimes);
- int i = 0;
- for (; i < ntimes / 2 - 1; ++i) {
- int time1 = times[1] + times[0] + times[ntimes-2*i-1] + times[1];
- int time2 = times[ntimes-2*i-1] + times[0] + times[ntimes-2*i-2] + times[0];
- if (time1 < time2) {
- strategy[4*i+1][0] = times[0];
- strategy[4*i+1][1] = times[1];
- strategy[4*i+2][0] = times[0];
- strategy[4*i+3][0] = times[ntimes-2*i-2];
- strategy[4*i+3][1] = times[ntimes-2*i-1];
- strategy[4*i+4][0] = times[1];
- strategy[0][0] += time1;
- } else {
- strategy[4*i+1][0] = times[0];
- strategy[4*i+1][1] = times[ntimes-2*i-1];
- strategy[4*i+2][0] = times[0];
- strategy[4*i+3][0] = times[0];
- strategy[4*i+3][1] = times[ntimes-2*i-2];
- strategy[4*i+4][0] = times[0];
- strategy[0][0] += time2;
- }
- }
- strategy[4*i+1][0] = times[0];
- strategy[4*i+1][1] = times[1];
- strategy[0][0] += times[1];
- if (ntimes % 2 == 1) {
- strategy[4*i+2][0] = times[0];
- strategy[4*i+3][0] = times[0];
- strategy[4*i+3][1] = times[2];
- strategy[0][0] += times[0] + times[2];
- }
- }
- int main(int argc, char *argv[])
- {
- #ifndef ONLINE_JUDGE
- filebuf in, out;
- cin.rdbuf(in.open((string(argv[0]) + ".in").c_str(), ios_base::in));
- cout.rdbuf(out.open((string(argv[0]) + ".out").c_str(), ios_base::out));
- #endif
- int ncases;
- cin >> ncases;
- while (ncases-- > 0) {
- int ntimes;
- cin >> ntimes;
- int times[timecount];
- for (int i = 0; i < ntimes; ++i) cin >> times[i];
- if (ntimes < 2) {
- cout << times[0] << '/n' << times[0] << '/n';
- } else {
- int strategy[(timecount-1)*2][2] = {{0}};
- cross_bridge(times, ntimes, strategy);
- for (int i = 0; i < (ntimes - 1) * 2; ++i) {
- cout << strategy[i][0];
- if (i % 2 == 1) cout << ' ' << strategy[i][1];
- cout << '/n';
- }
- }
- if (ncases > 0) cout << '/n';
- }
- return 0;
- }