POJ-1700 & NYOJ 47 cross river problems [greedy], pattern nail painting 1700
Link: NYOJ: click here POJ: click here
Question:
In the dark night, N travelers came to a narrow bridge without guardrails. If you do not use a flashlight, you will not dare to cross the bridge in any way. Unfortunately, N people only carry one flashlight, while the bridge is narrow enough to let two people pass simultaneously. If they bridge the bridge separately, the time required by N people is known. If the two bridge the bridge at the same time, the time required is the time required for a person to take action slowly. The problem is how to design a scheme to allow the N people to bridge the bridge as soon as possible.
Ideas:
Greedy ideas (generally sorted first)
Each time two people move from the bank to the other side, either one of them is the fastest person in time, or they will never come back after they arrive on the other side. That is: either the fastest + slowest (the fastest way back to change people), or the slowest + slow (not coming back ).
1. Sort the time for N people to cross the river from small to large. Cost [I];
2. Analysis:
(1) When n = 1, cross the river directly. Sum = cost [0]
(2) When n = 2, cross the river directly. Sum = cost [1]
(3) When n = 3, sum = cost [0] + cost [1] + cost [2]
(4) When n = 4, a = cost [0], B = cost [1], c = cost [2], d = cost [3];
Send with the smallest value: B + a + c + a + d = 2 * a + B + c + d = 2 * cost [0] + cost [1] + cost [2] + cost [3] (, B used to, a came back, a, c used to, a came back, a, d used)
Send two orders: B + a + d + B = a + 3 * B + d = cost [0] + 3 * cost [1] + cost [3] (a, B used, a back, c, d past, B back, a, B past)
So sum = min (2a + B + c + d, a + 3b + d)
(5) When n> 4, a, B ,......, C, d, more than 4 people, a and B are the smallest two people, c and d are the largest two people, and the goal is to send the largest two people to the past. The minimum sacrifice is required.
Send with minimal: A = d + a + c + a = 2a + c + d = 2 * cost [0] + cost [2] + cost [3] (, d used to, a came back, a and c used to, and a came back)
The two are sent to the two major accounts: B = B + a + d + B = a + 2b + d = cost [0] + 2 * cost [1] + cost [3]; (a and B are in the past, a is back, c and d is in the past, and B is back)
Loop: sum = min (A,B) Until n <= 4.
The idea is clear and the code is not difficult to implement:
// NYOJ 47 cross-river: // POJ 1007 # include <stdio. h> # include <string. h >#include <iostream >#include <algorithm> using namespace std; int cost [1010]; int main () {// freopen ("1.txt"," r ", stdin); // freopen ("2.txt"," w ", stdout); int ncase, m, n, I, j; int sum; scanf (" % d ", & ncase); while (ncase --) {sum = 0; scanf ("% d", & m); memset (cost, 0, sizeof (cost )); for (I = 0; I <m; I ++) scanf ("% d", & cost [I]); sort (cost, cost + m ); while (m) {if (m = 1) {sum + = cost [0]; break;} else if (m = 2) {sum + = cost [1]; break;} else if (m = 3) {sum + = (cost [0] + cost [1] + cost [2]); break;} else if (m = 4) {if (m = 4) sum + = min (2 * cost [0] + cost [1] + cost [2] + cost [3], cost [0] + 3 * cost [1] + cost [3]); break ;} else {// if (cost [m-2]-2 * cost [1] + cost [0] <= 0) // sum + = min (cost [M-1] + cost [m-2] + 2 * cost [0],) sum + = min (cost [M-1] + cost [m-2] + 2 * cost [0], cost [M-1] + 2 * cost [1] + cost [0]); m-= 2 ;}} printf ("% d \ n", sum) ;}return 0 ;}