<!--
@page { margin: 0.79in }
H2 { margin-top: 0.18in; margin-bottom: 0.18in; line-height: 173%; page-break-inside: avoid }
H2.western { font-family: "Arial", sans-serif; font-size: 16pt }
H2.cjk { font-family: "黑體", "SimHei"; font-size: 16pt }
H2.ctl { font-family: "DejaVu Sans"; font-size: 16pt }
P { margin-bottom: 0.08in }
-->
現在小明一家過一座橋,過橋的時候是黑夜,所以必須有燈。現在小明過橋要
1秒,小明的弟弟要
3秒,小明的爸爸要
6秒,小明的媽媽要八秒,小明的爺爺要
12秒。每次此橋最多可過兩人,而過橋的速度依過橋最慢者而定,而且燈在點燃後
30秒就會熄滅。問小明一家如何過橋?(原本是個智力題,這裡用程式來求解)
方案: --> 3min 明、弟
<-- 1min 明
--> 6min 明、爸
<-- 1min 明
--> 12min 明、爺
<-- 3min 弟
--> 3min 明、弟 總時間: 29min
總結:一定要讓弟弟(時間次小)的充當一次送燈人,而且最長的兩個時間要一起過來,這樣的話,弟弟(次小時間的人)將會起到送燈作用。
代碼: (使用遞迴計算)
#include "stdio.h"<br />#define N 5<br />#define SIZE 64<br />// 將人員編號:小明-0,弟弟-1,爸爸-2,媽媽-3,爺爺-4<br />// 每個人的當前位置:0--在橋左邊, 1--在橋右邊<br />int Position[N];<br />// 過橋臨時方案的數組下標; 臨時方案; 最小時間方案;<br />int Index, TmpScheme[SIZE], Scheme[SIZE];<br />// 最小過橋時間總和,初始值100;每個人過橋所需要的時間<br />int MinTime=100, Time[N]={1, 3, 6, 8, 12};<br />// 尋找最佳過橋方案。Remnant:未過橋人數; CurTime:當前經過時間;<br />// Direction:過橋方向,1--向右,0--向左<br />void Find(int Remnant,int CurTime,int Direction)<br />{<br /> //所有的人已經過橋,更新最小時間及方案<br /> if(Remnant == 0)<br /> {<br /> MinTime = CurTime;<br /> for(int i=0;i<SIZE && TmpScheme[i]>=0;i++)<br /> Scheme[i] = TmpScheme[i];<br /> }<br /> else if(Direction == 1) //過橋方向為右,從橋的左側選出兩個人過橋<br /> {<br /> for(int i=0;i<N;i++)<br /> {<br /> if(Position[i] == 0 && CurTime+Time[i]<MinTime)<br /> {<br /> TmpScheme[Index++] = i;<br /> Position[i] = 1;<br /> for(int j=0;j<N;j++)<br /> {<br /> int TmpMax = (Time[i]>Time[j] ? Time[i]:Time[j]);<br /> if(Position[j] == 0 && CurTime+TmpMax<MinTime)<br /> {<br /> TmpScheme[Index++] = j;<br /> Position[j] = 1;<br /> Find(Remnant-2,CurTime+TmpMax,!Direction);<br /> Position[j] = 0;<br /> TmpScheme[--Index] = -1;<br /> }<br /> }<br /> Position[i] = 0;<br /> TmpScheme[--Index] = -1;<br /> }<br /> }<br /> }<br /> else //過橋方向向左,從橋右邊選出一個人過來送燈<br /> {<br /> for(int j=0;j<N;j++)<br /> {<br /> if(Position[j] == 1 && CurTime+Time[j]<MinTime)<br /> {<br /> TmpScheme[Index++] = j;<br /> Position[j] = 0;<br /> Find(Remnant+1,CurTime+Time[j],!Direction);<br /> Position[j] = 1;<br /> TmpScheme[--Index] = -1;<br /> }<br /> }<br /> }<br />}<br />int main()<br />{<br /> for(int i=0;i<SIZE;i++) //初始方案內容為負值,避免與人員標號衝突<br /> Scheme[i] = TmpScheme[i] = -1;<br /> Find(N,0,1);<br /> printf("MinTime = %d:",MinTime);<br /> for(int i=0;i<SIZE && Scheme[i]>=0;i+=3)<br /> printf(" %d-%d %d",Scheme[i],Scheme[i+1],Scheme[i+2]);<br /> printf(" --The last '-1' means calculate completely!");<br /> getchar(); //如果不使用getchar(),程式運行一閃而過,將看不到結果<br /> //printf("/n"); //如果包含這行,就可以不要getchar()那行,會輸出一個斷行符號再退出<br /> return 0;<br />}