




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
1、專題十:算法分析與設(shè)計1常用的算法設(shè)計方法:1.1 迭代法1.2 窮舉搜索法1.3 遞推法1.4 遞歸法1.5 貪婪法1.6 分治法1.7 動態(tài)規(guī)劃法1.8 回溯法算法基礎(chǔ)部分:算法是對特定問題求解步驟的一種描述,算法是指令的有限序列,其中每一條指令表示一個或多個操作。算法具有以下5個屬性:有窮性:一個算法必須總是在執(zhí)行有窮步之后結(jié)束,且每一步都在有窮時間內(nèi)完成。確定性:算法中每一條指令必須有確切的含義。不存在二義性。只有一個入口和一個出口可行性:一個算法是可行的就是算法描述的操作是可以通過已經(jīng)實現(xiàn)的基本運算執(zhí)行有限次來實現(xiàn)的。輸入:一個算法有零個或多個輸入,這些輸入取自于某個特定對象的集合。
2、輸出:一個算法有一個或多個輸出,這些輸出同輸入有著某些特定關(guān)系的量。所以對應(yīng)的算法設(shè)計的要求:正確性:算法應(yīng)滿足具體問題的需求;可讀性:算法應(yīng)該好讀,以有利于讀者對程序的理解;健壯性:算法應(yīng)具有容錯處理,當(dāng)輸入為非法數(shù)據(jù)時,算法應(yīng)對其作出反應(yīng),而不是產(chǎn)生莫名其妙的輸出結(jié)果。效率與存儲量需求:效率指的是算法執(zhí)行的時間;存儲量需求指算法執(zhí)行過程中所需要的最大存儲空間。一般這兩者與問題的規(guī)模有關(guān)。1.1 迭代法:迭代法是用于求方程或方程組近似根的一種常用的算法設(shè)計方法。設(shè)方程為f(x)=0,用某種數(shù)學(xué)方法導(dǎo)出等價的形式x=g(x),然后按以下步驟執(zhí)行:(1)選一個方程的近似根,賦給變量x
3、0;(2)將x0的值保存于變量x1,然后計算g(x1),并將結(jié)果存于變量x0;(3)當(dāng)x0與x1的差的絕對值還小于指定的精度要求時,重復(fù)步驟(2)的計算。若方程有根,并且用上述方法計算出來的近似根序列收斂,則按上述方法求得的x0就認(rèn)為是方程的根。上述算法用C程序的形式表示為:【算法】迭代法求方程的根 x0=初始近似根; do x1
4、=x0; x0=g(x1); /*按特定的方程計算新的近似根*/ while ( fabs(x0-x1)>Epsilon); printf(“方程的近似根是%fn”,x0);
5、迭代算法也常用于求方程組的根,令 X=(x0,x1,xn-1)設(shè)方程組為: xi=gi(X) (I=0,1,n-1)則求方程組根的迭代算法可描述如下:【算法】迭代法求方程組的根
6、160; for (i=0;i<n;i+) xi=初始近似根; do
7、60; for (i=0;i<n;i+) yi=xi;
8、 for (i=0;i<n;i+) xi=gi(X);
9、 for (delta=0.0,i=0;i<n;i+)if (fabs(yi-xi)>delta) delta=fabs(yi-xi);
10、; while (delta>Epsilon); for (i=0;i<n;i+) &
11、#160; printf(“變量x%d的近似根是 %f”,I,xi); printf(“n”); 具體使用迭代法求根時應(yīng)注意以下兩種可能發(fā)生的情況:(1)如果方程無解,算法求出的近似根序列就不會收斂,迭代過程會變成死循環(huán),因此在使用迭代算法前應(yīng)先考察方程是否有解,并在程序中對迭代的次數(shù)給予限制;(
12、2)方程雖然有解,但迭代公式選擇不當(dāng),或迭代的初始近似根選擇不合理,也會導(dǎo)致迭代失敗。1.2 窮舉搜索法:窮舉搜索法是對可能是解的眾多候選解按某種順序進行逐一枚舉和檢驗,并從中找出那些符合要求的候選解作為問題的解。要解決的問題只有有限種可能,在沒有更好算法時總可以用窮舉搜索的辦法解決,即逐個的檢查所有可能的情況??梢韵胂螅闆r較多時這種方法極為費時。實際上并不需要機械的檢查每一種情況,常常是可以提前判斷出某些情況不可能取到最優(yōu)解,從而可以提前舍棄這些情況。這樣也是隱含的檢查了所有可能的情況,既減少了搜索量,又保證了不漏掉最優(yōu)解。【問題】 將A、B、C、D、E、F這六個變量排成如圖所示
13、的三角形,這六個變量分別取1,6上的整數(shù),且均不相同。求使三角形三條邊上的變量之和相等的全部解。如圖就是一個解。程序引入變量a、b、c、d、e、f,并讓它們分別順序取1至6的整數(shù),在它們互不相同的條件下,測試由它們排成的如圖所示的三角形三條邊上的變量之和是否相等,如相等即為一種滿足要求的排列,把它們輸出。當(dāng)這些變量取盡所有的組合后,程序就可得到全部可能的解。細(xì)節(jié)見下面的程序。# include <stdio.h>void main() int a,b,c,d,e,f;
14、0; for (a=1;a<=6;a+) /a,b,c,d,e依次取不同的值 for (b=1;b<=6;b+)
15、60; if (b=a) continue; for (c=1;c<=6;c+)
16、; if (c=a)|(c=b) continue;
17、60; for (d=1;d<=6;d+)
18、; if (d=a)|(d=b)|(d=c) continue;for (e=1;e<=6;e+)
19、 if (e=a)|(e=b)|(e=c)|(e=d) continue;f=21-(a+b+c+d+e);/最后一個用減法算if (a+b+c=c+d+e)&&(a+b+c=e+f+a)
20、 printf(“%6d,a); printf(“%4d%4d”,b,f); printf(“%2d%4d%4d”,c,d,e); scanf(“%c”);
21、
22、;
23、60; 按窮舉法編寫的程序通常不能適應(yīng)變化的情況。如問題改成有9個變量排成三角形,每條邊有4個變量的情況,程序的循環(huán)重數(shù)就要相應(yīng)改變,循環(huán)的重數(shù)和變量的個數(shù)相關(guān)。從上述問題解決的方法中,最重要的因素就是確定某種方法來確定所有的候選解。下1.3 遞推法: 遞推法是利用問題本身所具有的一種遞推關(guān)系求問題解的一種方法。設(shè)要求問題規(guī)模為N的解,當(dāng)N=1時,解或為
24、已知,或能非常方便地得到解。能采用遞推法構(gòu)造算法的問題有重要的遞推性質(zhì),即當(dāng)?shù)玫絾栴}規(guī)模為i-1的解后,由問題的遞推性質(zhì),能從已求得的規(guī)模為1,2,i-1的一系列解,構(gòu)造出問題規(guī)模為I的解。這樣,程序可從i=0或i=1出發(fā),重復(fù)地,由已知至i-1規(guī)模的解,通過遞推,獲得規(guī)模為i的解,直至得到規(guī)模為N的解?!締栴}】 階乘計算問題描述:編寫程序,對給定的n(n100),計算并輸出k的階乘k?。╧=1,2,n)的全部有效數(shù)字。由于要求的整數(shù)可能大大超出一般整數(shù)的位數(shù),程序用一維數(shù)組存儲長整數(shù),存儲長整數(shù)數(shù)組的每個元素只存儲長整數(shù)的一位數(shù)字。如有m位成整數(shù)N用數(shù)組a 存儲:
25、60; N=am×10m-1+am-1×10m-2+ +a2×101+a1×100并用a0存儲長整數(shù)N的位數(shù)m,即a0=m。按上述約定,數(shù)組的每個元素存儲k的階乘k!的一位數(shù)字,并從低位到高位依次存于數(shù)組的第二個元素、第三個元素。例如,5!=120,在數(shù)組中的存儲形式為:3021 首元素3表示長整數(shù)是一個3位數(shù),接著是低位到高位依次是0、2、1,表示成整數(shù)120。 計算階乘k!可采用對已求得的階乘(k-
26、1)!連續(xù)累加k-1次后求得。例如,已知4!=24,計算5!,可對原來的24累加4次24后得到120。細(xì)節(jié)見以下程序。# include <stdio.h># include <malloc.h># define MAXN 1000void pnext(int a ,int k)/已知a中的(k-1)!,求出k!在a中。 int *b,m=a0,i,j,r,carry; b=(int * ) malloc
27、(sizeof(int)* (m+1); for ( i=1;i<=m;i+) bi=ai; for ( j=1;j<k;j+) /控制累加k-1次 for ( carry=0,i=1;i&
28、lt;=m;i+)/i存放的是整數(shù)的位數(shù) r=(i<a0?ai+bi:ai)+carry;/進位標(biāo)志 ai=r%
29、10; carry=r/10; i
30、f (carry) a+m=carry; free(b); a0=m;void write(int *a,int k)/功能是輸出累加K次后的數(shù)組的各個位 int i; printf(“%4d!=”,k);
31、0; for (i=a0;i>0;i-) printf(“%d”,ai);printf(“nn”);void main() int aMAXN,n,k; printf(“Enter the number n: “);
32、60; scanf(“%d”,&n); a0=1; a1=1; write(a,1); for (k=2;k<=n;k+) pnext(a,
33、k); write(a,k);/輸出長整數(shù)的各位 getchar(); 1.4 遞歸法 遞歸是設(shè)計和描述算法
34、的一種有力的工具,由于它在復(fù)雜算法的描述中被經(jīng)常采用,為此在進一步介紹其他算法設(shè)計方法之前先討論它。 能采用遞歸描述的算法通常有這樣的特征:為求解規(guī)模為N的問題,設(shè)法將它分解成規(guī)模較小的問題,然后從這些小問題的解方便地構(gòu)造出大問題的解,并且這些規(guī)模較小的問題也能采用同樣的分解和綜合方法,分解成規(guī)模更小的問題,并從這些更小問題的解構(gòu)造出規(guī)模較大問題的解。特別地,當(dāng)規(guī)模N=1時,能直接得解?!締栴}】編寫計算斐波那契(Fibonacci)數(shù)列的第n項函數(shù)fib(n)。斐波那契數(shù)列為:0、1、1、2、3、,即:
35、0; fib(0)=0; fib(1)=1; fib(n)=fib(n-1)+fib(n-2) &
36、#160; (當(dāng)n>1時)。寫成遞歸函數(shù)有: int fib(int n) if (n=0) return 0; if (n=1) return 1; if (n>1)
37、60; return fib(n-1)+fib(n-2); 遞歸算法的執(zhí)行過程分遞推和回歸兩個階段。在遞推階段,把較復(fù)雜的問題(規(guī)模為n)的求解推到比原問題簡單一些的問題(規(guī)模小于n)的求解。例如上例中,求解fib(n),把它推到求解fib(n-1)和fib(n-2)。也就是說,為計算fib(n),必須先計算fib(n-1)和fib(n-2),而計算fib(n-1)和fib(n-2),又必須先計算fib(n-3)和fib(n-4)。依次類推,直至計算fib(1)和f
38、ib(0),分別能立即得到結(jié)果1和0。在遞推階段,必須要有終止遞歸的情況。例如在函數(shù)fib中,當(dāng)n為1和0的情況。 在回歸階段,當(dāng)獲得最簡單情況的解后,逐級返回,依次得到稍復(fù)雜問題的解,例如得到fib(1)和fib(0)后,返回得到fib(2)的結(jié)果,在得到了fib(n-1)和fib(n-2)的結(jié)果后,返回得到fib(n)的結(jié)果。 在編寫遞歸函數(shù)時要注意,函數(shù)中的局部變量和參數(shù)只是局限于當(dāng)前調(diào)用層,當(dāng)遞推進入“簡單問題”層時,原來層次上的參數(shù)和局部變量便被隱蔽起來。在一系列“簡單問題”層,它們各有自己的參數(shù)和局部
39、變量。 由于遞歸引起一系列的函數(shù)調(diào)用,并且可能會有一系列的重復(fù)計算,遞歸算法的執(zhí)行效率相對較低。當(dāng)某個遞歸算法能較方便地轉(zhuǎn)換成遞推算法時,通常按遞推算法編寫程序。例如上例計算斐波那契數(shù)列的第n項的函數(shù)fib(n)應(yīng)采用遞推算法,即從斐波那契數(shù)列的前兩項出發(fā),逐次由前兩項計算出下一項,直至計算出要求的第n項。【問題】背包問題問題描述:有不同價值、不同重量的物品n件,求從這n件物品中選取一部分物品的選擇方案,使選中物品的總重量不超過指定的限制重量,但選中物品的價值之和最大。設(shè)n件物品的重量分別為w0、w1、wn-1,物品的價值分別為v0、v1、vn-
40、1。采用遞歸尋找物品的選擇方案。設(shè)前面已有了多種選擇的方案,并保留了其中總價值最大的方案于數(shù)組option ,該方案的總價值存于變量maxv。當(dāng)前正在考察新方案,其物品選擇情況保存于數(shù)組cop 。假定當(dāng)前方案已考慮了前i-1件物品,現(xiàn)在要考慮第i件物品;當(dāng)前方案已包含的物品的重量之和為tw;至此,若其余物品都選擇是可能的話,本方案能達(dá)到的總價值的期望值為tv。算法引入tv是當(dāng)一旦當(dāng)前方案的總價值的期望值也小于前面方案的總價值maxv時,繼續(xù)考察當(dāng)前方案變成無意義的工作,應(yīng)終止當(dāng)前方案,立即去考察下一個方案。因為當(dāng)方案的總價值不比maxv大時,該方案不會被再考察,這同時保證函數(shù)后找到的方案一定會
41、比前面的方案更好。對于第i件物品的選擇考慮有兩種可能:(1)考慮物品i被選擇,這種可能性僅當(dāng)包含它不會超過方案總重量限制時才是可行的。選中后,繼續(xù)遞歸去考慮其余物品的選擇。(2)考慮物品i不被選擇,這種可能性僅當(dāng)不包含物品i也有可能會找到價值更大的方案的情況。按以上思想寫出遞歸算法如下:try(物品i,當(dāng)前選擇已達(dá)到的重量和,本方案可能達(dá)到的總價值tv) /*考慮物品i包含在當(dāng)前方案中的可能性*/ if(包含物品i是可以接受的)
42、 將物品i包含在當(dāng)前方案中; if (i<n-1) try(i+1,tw+物品i的重量,tv);
43、160; else /*又一個完整方案,因為它比前面的方案好,以它作為最佳方案*/以當(dāng)前方案作為臨時最佳方案保存;
44、60; 恢復(fù)物品i不包含狀態(tài); /*考慮物品i不包含在當(dāng)前方案中的可能性*/
45、60; if (不包含物品i僅是可考慮的) if (i<n-1) &
46、#160; try(i+1,tw,tv-物品i的價值); else
47、60; /*又一個完整方案,因它比前面的方案好,以它作為最佳方案*/以當(dāng)前方案作為臨時最佳方案保存; 為了理解上述算法,特舉以下實例。設(shè)有4件物品,它們的重量和價值見表:物品0123重量5321價值4431 并設(shè)限制重量為7。則按以上算法,下圖表示找解過程。由圖知,一旦找到一個解,算法就進一步找更
48、好的解。如能判定某個查找分支不會找到更好的解,算法不會在該分支繼續(xù)查找,而是立即終止該分支,并去考察下一個分支。 Try(物品號,總重,價值)按上述算法編寫函數(shù)和程序如下:【程序】# include <stdio.h># define N 100double limitW,totV,maxV;int optionN,copN;struct
49、; double weight; double value;
50、; aN;int n;void find(int i,double tw,double tv) int k; /*考慮物品i包含在當(dāng)前方案中的可能性*/ if (tw+ai.weight<=limitW)
51、60; copi=1; if (i<n-1) find(i+1,tw+ai.weight,tv); else
52、160; for (k=0;k<n;k+) optionk=copk;
53、60; maxv=tv; copi=0; /*考慮物品i不包含在當(dāng)前方案中的可能性*/ if
54、(tv-ai.value>maxV) if (i<n-1) find(i+1,tw,tv-ai.value); else
55、 for (k=0;k<n;k+) optionk=copk; &
56、#160; maxv=tv-ai.value; void main() int k; double w,v; printf(“輸入物品種數(shù)n”);
57、; scanf(“%d”,&n); printf(“輸入各物品的重量和價值n”); for (totv=0.0,k=0;k<n;k+) scanf(“%1f%1f”,&w,&v);
58、160; ak.weight=w; ak.value=v; totV+=V;
59、60; printf(“輸入限制重量n”); scanf(“%1f”,&limitV); maxv=0.0; for (k=0;k<n;k+) copk=0; find(0,0.0,totV); for (k=0;
60、k<n;k+) if (optionk) printf(“%4d”,k+1); printf(“n總價值為%.2fn”,maxv);作為對比,下面以同樣的解題思想,考慮非遞歸的程序解。為了提高找解速度,程序不是簡單地逐一生成所有候選解,而是從每個物品對候選解的影響來形成值得進一步考慮的候選解,一個候選解是通過依次考察每個物品形成的。對物品i
61、的考察有這樣幾種情況:1 當(dāng)該物品被包含在候選解中依舊滿足解的總重量的限制,該物品被包含在候選解中是應(yīng)該繼續(xù)考慮的;2 反之,該物品不應(yīng)該包括在當(dāng)前正在形成的候選解中。3 僅當(dāng)物品不被包括在候選解中,還是有可能找到比目前臨時最佳解更好的候選解時,才去考慮該物品不被包括在候選解中;4 該物品不包括在當(dāng)前候選解中的方案也不應(yīng)繼續(xù)考慮。5 對于任意一個值得考慮的餓方案,程序就去進一步考慮下一個物品;【程序】# include <stdio.h># define
62、; N 100double limitW;int copN;struct ele double weight;
63、0; double value; aN;int k,n;struct
64、160; int flg; double tw;
65、0; double tv; twvN;void next(int i,double tw,double tv) twvi.flg=1;
66、; twvi.tw=tw; twvi.tv=tv;double find(struct ele *a,int n) int i,k,f; double maxv,tw,tv,totv; maxv=0; for (to
67、tv=0.0,k=0;k<n;k+) totv+=ak.value; next(0,0.0,totv); i=0; While (i>=0) &
68、#160; f=twvi.flg; tw=twvi.tw; tv=twvi.tv; switch
69、(f) case 1: twvi.flg+; &
70、#160; if (tw+ai.weight<=limitW)
71、160; if (i<n-1)
72、; next(i+1,tw+ai.weight,tv);
73、160; i+;
74、60; else
75、0; maxv=tv;
76、 for (k=0;k<n;k+)
77、0; copk=twvk.flg!=0;
78、0;
79、60; break; case 0: i-;
80、160; break;
81、default: twvi.flg=0; if (tv-ai.value>maxv)
82、60; if (i<n-1) &
83、#160; next(i+1,tw,tv-ai.value);
84、0; i+;
85、
86、; else
87、; maxv=tv-ai.value;
88、0; for (k=0;k<n;k+)
89、160; copk=twvk.flg!=0;
90、160; &
91、#160; break; return maxv;void main() double maxv; printf(“輸入物品種數(shù)n”);
92、160; scanf(“%d”,&n); printf(“輸入限制重量n”); scanf(“%1f”,&limitW);printf(“輸入各物品的重量和價值n”); for (k=0;k<n;k+)
93、160; scanf(“%1f%1f”,&ak.weight,&ak.value); maxv=find(a,n); printf(“n選中的物品為n”);for (k=0;k<n;k+) if (optionk) printf(“%4d”,
94、k+1); printf(“n總價值為%.2fn”,maxv);1.5 貪婪法 貪心法是求解關(guān)于獨立系統(tǒng)組合優(yōu)化問題的一種簡單算法,求最小生成樹的Kruskal算法就是一種貪心算法。貪心法的基本思路是:從問題的某一個初始解出發(fā)逐步逼近給定的目標(biāo),以盡可能快的地求得更好的解。當(dāng)達(dá)到某算法中的某一步不能再繼續(xù)前進時,算法停止。 該算法存在問題: 1. 不能保證求得的最后解是最佳的; 2. 不能用來求最大或最小解問題; 3. 只能求滿足某些約束條件的可行解的范圍。 實現(xiàn)
95、該算法的過程: 從問題的某一初始解出發(fā); while 能朝給定總目標(biāo)前進一步 do 求出可行解的一個解元素; 由所有解元素組合成問題的一個可行解;貪婪法是一種不追求最優(yōu)解,只希望得到較為滿意解的方法。貪婪法一般可以快速得到滿意的解,因為它省去了為找最優(yōu)解要窮盡所有可能而必須耗費的大量時間。貪婪法常以當(dāng)前情況為基礎(chǔ)作最優(yōu)選擇,而不考慮各種可能的整體情況,所以貪婪法不要回溯。 例如平時購物找錢時,為使找回的零錢的硬幣數(shù)最少,不考慮找零錢的所有各種發(fā)表方案,而是從最大面值的幣種開始,按遞減的順序考慮各幣種,先盡量用大面值的幣種,當(dāng)不足大面值
96、幣種的金額時才去考慮下一種較小面值的幣種。這就是在使用貪婪法。這種方法在這里總是最優(yōu),是因為銀行對其發(fā)行的硬幣種類和硬幣面值的巧妙安排。如只有面值分別為1、5和11單位的硬幣,而希望找回總額為15單位的硬幣。按貪婪算法,應(yīng)找1個11單位面值的硬幣和4個1單位面值的硬幣,共找回5個硬幣。但最優(yōu)的解應(yīng)是3個5單位面值的硬幣。【問題】裝箱問題問題描述:裝箱問題可簡述如下:設(shè)有編號為0、1、n-1的n種物品,體積分別為v0、v1、vn-1。將這n種物品裝到容量都為V的若干箱子里。約定這n種物品的體積均不超過V,即對于0in,有0viV。不同的裝箱方案所需要的箱子數(shù)目可能不同。裝箱問題要求使裝盡這n種物
97、品的箱子數(shù)要少。 若考察將n種物品的集合分劃成n個或小于n個物品的所有子集,最優(yōu)解就可以找到。但所有可能劃分的總數(shù)太大。對適當(dāng)大的n,找出所有可能的劃分要花費的時間是無法承受的。為此,對裝箱問題采用非常簡單的近似算法,即貪婪法。該算法依次將物品放到它第一個能放進去的箱子中,該算法雖不能保證找到最優(yōu)解,但還是能找到非常好的解。不失一般性,設(shè)n件物品的體積是按從大到小排好序的,即有v0v1vn-1。如不滿足上述要求,只要先對這n件物品按它們的體積從大到小排序,然后按排序結(jié)果對物品重新編號即可。裝箱算法簡單描述如下: &
98、#160; 輸入箱子的容積; 輸入物品種數(shù)n; 按體積從大到小順序,輸入各物品的體積; 預(yù)置已用箱子鏈為空; 預(yù)置已用箱子計數(shù)器box_count為0; for (i=0;i<n;i+)
99、 從已用的第一只箱子開始順序?qū)ふ夷芊湃胛锲穒 的箱子j; if (已用箱子都不能再放物品i) 另用一個箱子j,并將物品i放入該箱子;
100、0; box_count+; else
101、0; 將物品i放入箱子j; 上述算法能求出需要的箱子數(shù)box_count,并能求出各箱子所裝物品。下面的例子說明該算法不一定能找到最優(yōu)解,設(shè)有6種物品,它們的體積分別為:60、45、35、20、20和20單位體積,箱子的容積為100個單位體積。按上述算法計算,需三只箱子,各
102、箱子所裝物品分別為:第一只箱子裝物品1、3;第二只箱子裝物品2、4、5;第三只箱子裝物品6。而最優(yōu)解為兩只箱子,分別裝物品1、4、5和2、3、6。 若每只箱子所裝物品用鏈表來表示,鏈表首結(jié)點指針存于一個結(jié)構(gòu)中,結(jié)構(gòu)記錄尚剩余的空間量和該箱子所裝物品鏈表的首指針。另將全部箱子的信息也構(gòu)成鏈表。以下是按以上算法編寫的程序。【程序】# include <stdio.h># include <stdlib.h>typedef struct ele
103、int vno; struct ele *link; ELE;typedef struct hnode int remainder; ELE *head; Struct hnode
104、 *next; HNODE;void main() int n, i, box_count, box_volume, *a; HNODE *box_h, *box_t, *j; ELE *p, *q;
105、Printf(“輸入箱子容積n”); Scanf(“%d”,&box_volume); Printf(“輸入物品種數(shù)n”); Scanf(“%d”,&n); A=(int *)malloc(sizeof(int)*n); P
106、rintf(“請按體積從大到小順序輸入各物品的體積:”); For (i=0;i<n;i+) scanf(“%d”,a+i); Box_h=box_t=NULL; Box_count=0; For (i=0;i<n;i+)
107、60; p=(ELE *)malloc(sizeof(ELE); p->vno=i; for (j=box_h;j!=NULL;j=j->next)
108、60; if (j->remainder>=ai) break; if (j=NULL)
109、0; j=(HNODE *)malloc(sizeof(HNODE); j->remainder=box_volume-ai;
110、; j->head=NULL; if (box_h=NULL) box_h=box_t=j;
111、; else box_t=boix_t->next=j; j->next=NULL;
112、; box_count+; else j->remainder-=ai;
113、160; for (q=j->next;q!=NULL&&q->link!=NULL;q=q->link); if (q=NULL) p->
114、;link=j->head; j->head=p;
115、0; else p->link=NULL; q->link=p;
116、60; printf(“共使用了%d只箱子”,box_count); printf(“各箱子裝物品情況如下:”); for (j=box_h,i=1;j!=NULL;j=j->next,i+) &
117、#160; printf(“第%2d只箱子,還剩余容積%4d,所裝物品有;n”,I,j->remainder); for (p=j->head;p!=NULL;p=p->link)
118、160; printf(“%4d”,p->vno+1); printf(“n”); 1.6 分治法1分治法的基本思想任何一個可以用計算機求解的問題所需的計算時間都與其規(guī)模N有關(guān)。問題的規(guī)模越小,越容易直接求解,解題所需的計算時間也越少。例如,對于n個元素的排序問題,當(dāng)n=1時,不需任何計算;n
119、=2時,只要作一次比較即可排好序;n=3時只要作3次比較即可,。而當(dāng)n較大時,問題就不那么容易處理了。要想直接解決一個規(guī)模較大的問題,有時是相當(dāng)困難的。分治法的設(shè)計思想是,將一個難以直接解決的大問題,分割成一些規(guī)模較小的相同問題,以便各個擊破,分而治之。如果原問題可分割成k個子問題(1<kn),且這些子問題都可解,并可利用這些子問題的解求出原問題的解,那么這種分治法就是可行的。由分治法產(chǎn)生的子問題往往是原問題的較小模式,這就為使用遞歸技術(shù)提供了方便。在這種情況下,反復(fù)應(yīng)用分治手段,可以使子問題與原問題類型一致而其規(guī)模卻不斷縮小,最終使子問題縮小到很容易直接求出其解。這自然導(dǎo)致遞歸過程的產(chǎn)生。分治與遞歸像一對孿生兄弟,經(jīng)常同時應(yīng)用在算法設(shè)計之中,并由此產(chǎn)生許多高效算法。2分治法的適用條件分治法所能解決的問題一般具有以下幾個特征:(1)該問題的規(guī)??s小到一定的程度就可以容易地解決;(2)該問題可以分解為若干個規(guī)模較小的相同問題,即該問題具有最優(yōu)子結(jié)構(gòu)性質(zhì);(3)利用該問題分解出的子問題的解可以合并為該問題的解;(4)該問題所分解出的各個子問題是相互獨立的,即子問題之間不包含公共的子問題。 第一條特征是絕大多數(shù)問題都可以滿足的,因為問題的計算復(fù)雜性一般是隨著問題規(guī)模的增加而增加;第二條特征是應(yīng)用分治法的前提,它也是
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年文化遺產(chǎn)數(shù)字化展示與傳播在文化遺產(chǎn)資源整合中的應(yīng)用策略報告
- 個人征信逾期情況說明與還款計劃
- 北師大七年級數(shù)學(xué)競賽輔導(dǎo)計劃
- 在線編程教育平臺:2025年智能教學(xué)系統(tǒng)開發(fā)與實施報告
- 2025年春小學(xué)語文教研組教師培訓(xùn)計劃
- 施工現(xiàn)場安全管理準(zhǔn)備計劃
- 四年級美術(shù)教育主題活動計劃
- 2025年天然氣水合物開采技術(shù)預(yù)研報告:可燃冰開采技術(shù)裝備的耐磨性與耐腐蝕性研究
- 礦山整合項目融資協(xié)議書示例
- 藝術(shù)類院校教研組教學(xué)計劃
- 肺炎住院病歷及病程記錄教學(xué)文案
- 檢察院書記員考試試題法院書記員考試試題
- 金風(fēng)科技5MW風(fēng)力發(fā)電機專業(yè)題庫分解
- 排球比賽計分表2
- 水中樁、水上平臺施工專項方案
- 儀器設(shè)備管理培訓(xùn)課件(共88頁).ppt
- 食堂食品定點采購詢價記錄表
- Fuji Flexa程序制作步驟
- 深國交數(shù)學(xué)模擬試題1
- ICOM 2720中文說明書
- 關(guān)于琿春市水產(chǎn)業(yè)發(fā)展情況的調(diào)研報告
評論
0/150
提交評論