過橋問題
問題描述:晚上有四個人要過橋,只有一個手電筒,每次過橋都需要手電筒,每次最多可同時過兩個人,其中甲過橋要1分鍾,乙要2分鍾,丙要5分鍾,丁要10分鍾。求最短的過橋時間。
對於這個問題:我們可以引申到一個人,二個人,三個人至N個人過橋的問題上;
當一個人過橋時 那么直接過橋就行了 這很簡單
當兩個人過橋時,也是直接過橋 時間 = 走路最慢的那個人的時間;
當三個人過橋的時候 ,我們可以窮舉三個人過橋的可能性,發現 總共花費的最短時間 = 三個人的過橋時間和
當四個人過橋的時候 過橋的時間最短有兩種模式:
- 模式一 :讓速度最快的人 依次帶速度最慢的人和速度次慢的人 過橋
- 模式二 :讓速度最快的人和速度次快的人帶速度最慢的人和速度次慢的人過橋
當五個人過橋的時候 過橋的時間最短有兩種模式:
- 模式一 :讓速度最快的人 依次帶速度最慢的人和速度次慢的人 過橋,然后再看剩下三個人怎么辦
- 模式二 :讓速度最快的人和速度次快的人帶速度最慢的人和速度次慢的人過橋,然后再看剩下三個人怎么辦
當五個人過橋的時候 過橋的時間最短有兩種模式:
- 模式一 :讓速度最快的人 依次帶速度最慢的人和速度次慢的人 過橋,然后再看剩下四個人遞歸方法
- 模式二 :讓速度最快的人和速度次快的人帶速度最慢的人和速度次慢的人過橋,然后再看剩下四個人遞歸方法
模式一和模式二具體看這個鏈接的第十條:http://www.360doc.com/content/08/0706/02/37063_1402145.shtml
假設 :A : 速度最快 B :速度次快 C:速度次慢 D:速度最慢
模式二: times = time1+2+3+4;
a,b —> a,b time1
a <— a time2
z,y —> z,y time3
b <— b time4
下面是用JAVA寫的完整代碼
import java.util.Arrays; import java.util.Scanner; public class guohe { public static void main(String[] args) { System.out.println("請輸入過河人數:\n"); Scanner scanner=new Scanner(System.in); int n=scanner.nextInt(); System.out.println("請分別輸入這"+n+"個人過河時間"); int[] arr=new int[n]; for(int i=0;i<arr.length;i++){ arr[i]=scanner.nextInt(); } Arrays.sort(arr);//數組從小到大排序 System.out.println(shorts(arr,n)); } static int shorts(int arr[],int n) { int end = n;//n表示人數 int times = 0;//最短時間和 if (1 == n) { return arr[n - 1]; } if (2==n){ return arr[n-1]; } if (3==n){ return arr[0]+arr[1]+arr[2]; } if (n>=4){ //a是最快,b次最快,z最慢,y次最慢 int a=arr[0], b=arr[1], z=arr[n-1], y=arr[n-2]; //a先把b運過去,然后最快的a把z,y分別別來回運過去表示2*a+z+y //a先把b運過去,然后a過來,z和y一塊過去,b過來再把a運過去 if (2*a+z+y>2*b+a+z){ times=2*b+a+z; end=end-2;//上面的times只是把前四個里面的最慢和次最慢運過去了,所以在下面的代碼中再調用 }else{ times=2*a+z+y; end=end-2; } times=times+shorts(arr,end);//此處遞歸調用方法 } return times; } }