|
一找最大和最小元素與歸并分類算法實現(xiàn)(用分治法)
一、實驗?zāi)康?br />
1.掌握能用分治法求解的問題應(yīng)滿足的條件;
2.加深對分治法算法設(shè)計方法的理解與應(yīng)用;
3.鍛煉學(xué)生對程序跟蹤調(diào)試能力;
4.通過本次實驗的練習(xí)培養(yǎng)學(xué)生應(yīng)用所學(xué)知識解決實際問題的能力。
二.實驗內(nèi)容
(1)找最大最小元素:輸入n個數(shù),找出最大和最小數(shù)的問題。
(2)歸并分類:對n個數(shù)用歸并方法排序。
三.實驗要求
(1)用分治法求解問題
(2)上機(jī)實現(xiàn)所設(shè)計的算法;
四.實驗過程設(shè)計(算法設(shè)計過程)
常規(guī)的做法是遍歷一次,分別求出最大值和最小值,但我這里要說的是分治法(Divide and couquer),將數(shù)組分成左右兩部分,先求出左半部份的最大值和最小值,再求出右半部份的最大值和最小值,然后綜合起來求總體的最大值及最小值。這是個遞歸過程,對于劃分后的左右兩部分,同樣重復(fù)這個過程,直到劃分區(qū)間內(nèi)只剩一個元素或者兩個元素。
解決問題的策略:
蠻力策略:對金塊逐個進(jìn)行比較查找。(掃描數(shù)組一輪,尋找最大和最小的數(shù)。)該策略需要進(jìn)行(n-1)次的比較才能得到max和min。
分治法(二分法)策略:問題可以簡化為在n個數(shù)里面尋找最大和最小值。
(1)將數(shù)據(jù)等分為兩組(兩組數(shù)據(jù)的個數(shù)可能相差1),目的是分別選取其中的最大(。┲。
(2)遞歸分解直到每組元素的個數(shù)<=2,則可以簡單地找到其中的最大(小)值。
(3)回溯時合并子問題的解,在兩個子問題的解中大者取大,小者取小,即合并為當(dāng)前問題的解。
五.源代碼
(1)找最大最小元素:
- #include <iostream>
- using namespace std;
-
- void findMinMax(int a[],int l,int r,int *maxnum,int *minnum){
- if(l==r){//如果只有一個元素,則最小最大都是這個元素
- *maxnum = *minnum = a[l];
- return;
- }
- int mid,lmin,rmin,lmax,rmax;
- mid = (l+r)/2;
- findMinMax(a,l,mid,&lmax,&lmin);//尋找數(shù)組左邊的最大最小元素
- findMinMax(a,mid+1,r,&rmax,&rmin);//尋找數(shù)組右邊的最大最小元素
- *maxnum = lmax>rmax?lmax:rmax;//比較左右邊的最大元素找出更大的
- *minnum = lmin<rmin?lmin:rmin;//比較左右邊的最小元素找出更小的
- }
- int main()
- {
- int a[] = {1,2,3,4,5,6,7,8,9};
- int max,min;
- findMinMax(a,0,8,&max,&min);
- cout<<"max = "<<max<<"\n";
- cout<<"min = "<<min<<"\n";
- return 0;
- }
復(fù)制代碼
程序運行結(jié)果如下圖所示: (2)歸并分類:
- #include <stdio.h>
- #include <stdlib.h>
- void merge(int low,int mid,int high,int a[]){
- int h,i,j,k;
- h = i = low;
- j = mid+1;//把數(shù)組a從mid分成兩個集合
- int b[high];//數(shù)組b為輔助數(shù)組
- while(h <= mid && j <= high){//當(dāng)兩個集合都沒有取盡時
- if(a[h] <= a[j]){
- b[i] = a[h];
- h++;
- }else{
- b[i] = a[j];
- j++;
- }
- i++;
- }
- /*處理剩余的元素*/
- if(h > mid){//前一個數(shù)組先取完
- for(k = j;k <= high;k++){
- b[i] = a[k];
- i++;
- }
- }else{//后一個數(shù)組先取完
- for(k = h;k <= mid;k++){
- b[i] = a[k];
- i++;
- }
- }
- /*將已經(jīng)合并的集合從輔助數(shù)組復(fù)制到原數(shù)組*/
- for(k = low;k <= high;k++){
- a[k] = b[k];
- }
- }
-
- void mergeSort(int low,int high,int a[]){
- if(low < high){
- int mid = (low+high)/2;//求集合的分割點
- mergeSort(low,mid,a);//將前半個集合分類
- mergeSort(mid+1,high,a);//將后半個集合分類
- merge(low,mid,high,a);//歸并兩個已經(jīng)分類的集合
- }
- }
-
- int main()
- {
- int a[] = {2,4,3,6,1,7,8,5,9};
- mergeSort(0,8,a);
- for(int i = 0;i <= 6;i++){
- printf("\t%d\n",a[i]);
- }
- return 0;
- }
復(fù)制代碼
程序運行結(jié)果如下圖所示: 
實驗二 背包問題和最小生成樹算法實現(xiàn)(用貪心法)
一、實驗?zāi)康?br />
1.掌握能用貪心法求解的問題應(yīng)滿足的條件;
2.加深對貪心法算法設(shè)計方法的理解與應(yīng)用;
3.鍛煉學(xué)生對程序跟蹤調(diào)試能力;
4.通過本次實驗的練習(xí)培養(yǎng)學(xué)生應(yīng)用所學(xué)知識解決實際問題的能力。
二.實驗內(nèi)容
有一個背包,背包容量是M=150。有7個物品,物品可以分割成任意大小。要求盡可能讓裝入背包中的物品總價值最大,但不能超過總?cè)萘俊?br />
三.實驗要求
(1)用貪心法求解背包問題;
(2)上機(jī)實現(xiàn)所設(shè)計的算法;
四.實驗過程設(shè)計(算法設(shè)計過程)
貪心算法(又稱貪婪算法)是指,在對問題求解時,總是做出在當(dāng)前看來是最好的選擇。也就是說,不從整體最優(yōu)上加以考慮,他所做出的是在某種意義上的局部最優(yōu)解。
貪心算法不是對所有問題都能得到整體最優(yōu)解,關(guān)鍵是貪心策略的選擇,選擇的貪心策略必須具備無后效性,即某個狀態(tài)以前的過程不會影響以后的狀態(tài),只與當(dāng)前狀態(tài)有關(guān)。
基本思路
建立數(shù)學(xué)模型來描述問題;
把求解的問題分成若干個子問題;
對每一子問題求解,得到子問題的局部最優(yōu)解;
把子問題的解局部最優(yōu)解合成原來解問題的一個解。
算法實現(xiàn)
從問題的某個初始解出發(fā)。
采用循環(huán)語句,當(dāng)可以向求解目標(biāo)前進(jìn)一步時,就根據(jù)局部最優(yōu)策略,得到一個部分解,縮小問題的范圍或規(guī)模。
將所有部分解綜合起來,得到問題的最終解。
實例分析
實例1 背包問題
問題描述
有一個背包,背包容量是M=150。有7個物品,物品可以分割成任意大小。要求盡可能讓裝入背包中的物品總價值最大,但不能超過總?cè)萘俊?/div> - 問題分析
1.目標(biāo)函數(shù): ∑pi最大,使得裝入背包中的所有物品pi的價值加起來最大。
2.約束條件:裝入的物品總重量不超過背包容量:∑wi<=M( M=150)
3.貪心策略:
- 選擇價值最大的物品
- 選擇價值最大的物品
- 選擇單位重量價值最大的物品
有三個物品A,B,C,其重量分別為{30,10,20},價值分別為{60,30,80},背包的容量為50,分別應(yīng)用三種貪心策略裝入背包的物品和獲得的價值如下圖所示:
三種策略 - 計算出每個物品單位重量的價值
- 按單位價值從大到小將物品排序
- 根據(jù)背包當(dāng)前所剩容量選取物品
- 如果背包的容量大于當(dāng)前物品的重量,那么就將當(dāng)前物品裝進(jìn)去。否則,那么就將當(dāng)前物品舍去,然后跳出循環(huán)結(jié)束。
五.源代碼
(1)背包問題
- #include <iostream>
- #include<algorithm>
- using namespace std;
- /*定義物品的結(jié)構(gòu)體*/
- struct Object{
- double weight;//物品重量
- double value;//物品價值
- double avg;//單位重量價值
- double prop;//放入比例:0表示沒有放入,1表示全部放入
- };
-
- /*定義物品排序的標(biāo)準(zhǔn)*/
- bool cmp(Object a,Object b){
- return a.avg>b.avg;
- }
-
- int main()
- {
- Object *ob;
- double volume;//背包容量
- int num;//物品種類
- double maxValue = 0;//背包中的最大價值
- cout<<"請輸入所有物品數(shù)量和背包容量\n";
- cin>>num>>volume;
- ob = new Object[num];
- /*初始化物品的重量和價值,并計算單位重量價值*/
- for(int i = 0;i<num;i++){
- cout<<"輸入第"<<i+1<<"個物品的重量和價值\n";
- cin>>ob[i].weight>>ob[i].value;
- ob[i].avg = ob[i].value/ob[i].weight;
- }
- sort(ob,ob+num,cmp);//物品按單位重量價值降序
- int i;
- /*開始裝入物品*/
- for(i = 0;i<num;i++){
- if(ob[i].weight <= volume){//如果這個物品能全部裝入
- volume = volume -ob[i].weight;
- ob[i].prop = 1;//表示全部裝入
- maxValue = maxValue + ob[i].value;
- } else{//這個物品已經(jīng)不能全部裝人
- break;
- }
- }
- if(i<num){//有一個物品不能全部裝入
- ob[i].prop = volume/ob[i].weight;//裝入的比例
- volume = 0;
- maxValue = maxValue + ob[i].prop*ob[i].value;
- }
- cout<<"放入的物品的重量,價值,比例\n";
- for(int i = 0;i<num;i++){
- cout<<ob[i].weight<<" "<<ob[i].value<<" "<<ob[i].prop<<"\n";
- }
- cout<<"放入物品的總價值:"<<maxValue;
- return 0;
- }
復(fù)制代碼
程序運行結(jié)果: (2)最小生成樹 - /*
- S:當(dāng)前已經(jīng)在聯(lián)通塊中的所有點的集合
- 1. dist[i] = inf
- 2. for n 次
- t<-S外離S最近的點
- 利用t更新S外點到S的距離
- st[t] = true
- n次迭代之后所有點都已加入到S中
- 聯(lián)系:Dijkstra算法是更新到起始點的距離,Prim是更新到集合S的距離
- */
- #include <iostream>
- #include <cstring>
- using namespace std;
- const int N = 510, INF = 0x3f3f3f3f;
-
- int n, m;//n=|V|,m=|E|
- int g[N][N], dist[N];
- //鄰接矩陣存儲所有邊
- //dist存儲其他點到S的距離
- bool st[N];
-
- int prim() {
- //如果圖不連通返回INF, 否則返回res
- memset(dist, INF, sizeof dist);
- int res = 0;
-
- for(int i = 0; i < n; i++) {
- int t = -1;
- for(int j = 1; j <= n; j++)
- if(!st[j] && (t == -1 || dist[t] > dist[j]))
- t = j;
- //尋找離集合S最近的點
- if(i && dist[t] == INF) return INF;
- //判斷是否連通,有無最小生成樹
-
- if(i) res += dist[t];
- //cout << i << ' ' << res << endl;
- st[t] = true;
- //更新最新S的權(quán)值和
-
- for(int j = 1; j <= n; j++) dist[j] = min(dist[j], g[t][j]);
- }
-
- return res;
- }
-
- int main() {
- cout << "頂點數(shù)和邊數(shù):" << endl;
- cin >> n >> m;//n=|V|,m=|E|
- int u, v, w;//u,v,w,表示點u和點v之間存在一條權(quán)值為w的邊
-
- for(int i = 1; i <= n; i++)
- for(int j = 1; j <= n; j++)
- if(i ==j) g[i][j] = 0;
- else g[i][j] = INF;
-
- while(m--) {
- cout<< "兩頂點和邊長:" << endl;
- cin >> u >> v >> w;
- g[u][v] = g[v][u] = min(g[u][v], w);
- }
- int t = prim();
- cout <<"最小生成樹的樹邊權(quán)重之和:"<< t << endl;
- }
復(fù)制代碼
程序運行結(jié)果:
實驗三 多段圖和貨郎擔(dān)問題算法實現(xiàn)(用動態(tài)規(guī)劃方法)
一.實驗?zāi)康?br />
1.掌握能用動態(tài)規(guī)劃方法求解的問題應(yīng)滿足的條件;
2.加深對動態(tài)規(guī)劃方法的理解與應(yīng)用;
3.鍛煉學(xué)生對程序跟蹤調(diào)試能力;
4.通過本次實驗的練習(xí)培養(yǎng)學(xué)生應(yīng)用所學(xué)知識解決實際問題的能力。
二.實驗內(nèi)容
(1)多段圖:對于任意數(shù)目的n個節(jié)點,分別用1~n編號,對于k段,分別用1~k編號,則這個問題歸結(jié)為在k段n個節(jié)點的帶權(quán)圖中尋找從節(jié)點1到節(jié)點n的最短路徑。(自己添加的內(nèi)容)
(2)貨郎擔(dān):對于任意數(shù)目的n個城市,分別用1~n編號,則這個問題歸結(jié)為在有向帶權(quán)圖中,尋找一條路徑最短的哈密爾頓回路問題。
三.實驗要求
(1)用動態(tài)規(guī)劃方法貨郎擔(dān)問題;實現(xiàn)多段圖問題
(2)上機(jī)實現(xiàn)所設(shè)計的算法;
四.實驗過程設(shè)計(算法設(shè)計過程)
動態(tài)規(guī)劃的思想實質(zhì)是分治思想和解決冗余。 與分治法類似的是,將原問題分解成若干個子問題,先求解子問題,再從這些子問題的解得到原問題的解。與分治法不同的是,經(jīng)分解的子問題往往不是互相獨立的。若用分治法來解,有些共同部分(子問題或子子問題)被重復(fù)計算了很多次。如果能夠保存已解決的子問題的答案,在需要時再查找,這樣就可以避免重復(fù)計算、節(jié)省時間。動態(tài)規(guī)劃法用一個表來記錄所有已解的子問題的答案。
動態(tài)規(guī)劃方法的基本思想是,把求解的問題分成許多階段或多個子問題,然后按順序求解各子問題。最后一個子問題就是初始問題的解。
由于動態(tài)規(guī)劃的問題有重疊子問題的特點,為了減少重復(fù)計算,對每一個子問題只解一次,將其不同階段的不同狀態(tài)保存在一個二維數(shù)組中。
五.源代碼
(1)多段圖 - #include <iostream>
- using namespace std;
- #define INFI 65535 //定義兩節(jié)點之間的最大路徑
- int c[12][12]; //兩節(jié)點之間路徑長度的數(shù)組
-
- /**/
- void FGRAPH(int n,int k){
- int cost[n];//第n個節(jié)點到最后一個節(jié)點的最端路徑
- for(int i = 0;i<n;i++){
- cost[i] = INFI;//初始化所有節(jié)點的最短路徑為無窮大
- }
- cost[n-1] = 0;
- int j,r;
- int p[k],d[n];//p為段決策,d為節(jié)點決策
- int min;
- /*尋找所有節(jié)點到最后一個節(jié)點的最短路徑和節(jié)點決策)*/
- for(j = n-2;j>=0;j--){
- min = INFI;
- for(r = 0;r<=n-1;r++){
- if(c[j][r]+cost[r]<min){
- min = c[j][r] + cost[r];
- d[j] = r; //r即為j節(jié)點的節(jié)點的決策
- }
- }
- cost[j] = min; //j節(jié)點的最短路徑
- }
- p[0] = 0;
- p[k-1] = n-1;
- for(int j = 1;j<=k-1;j++){
- p[j] = d[p[j-1]];//上一個段的段決策的節(jié)點決策即為下一個段的段決策
- }
- for(int j = 0;j<=k-1;j++){
- cout<<p[j]<<"\n";
- }
- }
- int main()
- {
- int N = 12;
- /*節(jié)點之間距離初始化*/
- for(int i = 0;i<N;i++){
- for(int j = 0;j<N;j++){
- if(i == j)
- c[i][j] = 0;
- else{
- c[i][j] = INFI;
- c[j][i] = INFI;
- }
-
- }
- }
- c[0][1] = 9;
- c[0][2] = 7;
- c[0][3] = 3;
- c[0][4] = 2;
- c[1][5] = 4;
- c[1][6] = 2;
- c[1][7] = 1;
- c[2][5] = 2;
- c[2][6] = 7;
- c[3][7] = 11;
- c[4][6] = 11;
- c[4][7] = 8;
- c[5][8] = 6;
- c[5][9] = 5;
- c[6][8] = 4;
- c[6][9] = 3;
- c[7][9] = 5;
- c[7][10] = 6;
- c[8][11] = 4;
- c[9][11] = 2;
- c[10][11] = 5;
- FGRAPH(N,5);//調(diào)用多段圖函數(shù)
- return 0;
- }
復(fù)制代碼
程序運行結(jié)果如下圖所示:
(2) 貨郎擔(dān) - #include<iostream>
- #include<iomanip>
- using namespace std;
-
- int n;
- int cost[20][20];
- bool done[20]={1};
- int start = 0; //從城市0開始
- int imin(int num, int cur)
- {
- if(num==1) //遞歸調(diào)用的出口
- return cost[cur][start]; //所有節(jié)點的最后一個節(jié)
- //最后返回 最后一個節(jié)點到起點的路徑
- int mincost = 10000;
- for(int i=0; i<n; i++)
- {
- cout<<i<<" i:"<<done[i]<<endl;
- if(!done[i] && i!=start) //該結(jié)點沒加入且非起始點
- {
- done[i] = 1; //遞歸調(diào)用時,防止重復(fù)調(diào)用
- int value = cost[cur][i] + imin(num-1, i);
- if(mincost > value)
- {
- mincost = value;
- cout<<mincost<<endl;
- }
- done[i] = 0;//本次遞歸調(diào)用完畢,讓下次遞歸調(diào)用
- }
- }
- return mincost;
- }
-
- int main()
- {
- n=4;
- int cc[4][4]={{0,4,1,3},{4,0,2,1},{1,2,0,5},{3,1,5,0}};
- for(int i=0; i<n; i++)
- {
- for(int j=0; j<n; j++)
- {
- cost[i][j]=cc[i][j];
- }
- }
- cout << imin(n, start) << endl;
- return 0;
- }
復(fù)制代碼
程序運行結(jié)果如下圖所示:
實驗四 皇后與子集和數(shù)問題算法實現(xiàn)(用回溯法) 一、實驗?zāi)康?/div> 1.掌握能用回溯法求解的問題應(yīng)滿足的條件; 2.加深對回溯法算法設(shè)計方法的理解與應(yīng)用; 3.鍛煉學(xué)生對程序跟蹤調(diào)試能力; 4.通過本次實驗的練習(xí)培養(yǎng)學(xué)生應(yīng)用所學(xué)知識解決實際問題的能力。 二.實驗內(nèi)容 (1)n皇后問題 由N2個方塊排成N行N列的正方形,稱為N元棋盤,在N元棋盤上放置N個皇后,如果某兩個皇后位于N元棋盤的同一行或同一列或同一斜線(斜率為±1)上,則稱它們在互相攻擊,試設(shè)計算法找出使N個皇后互不攻擊的所有布局。 (2)子集和數(shù)問題 子集和數(shù)問題是假定有n個不同的正數(shù)(通常稱為權(quán)),要求找出這些數(shù)中所有事的某和數(shù)為M的組合。 (1)我們假設(shè)一個前提條件:這些正數(shù)是按照非降次序排列的。 (2)引入一個記號:B(X(1),...,X(k))表示是否可以把第K個正數(shù)加入進(jìn)來,所以它的取指為true或者false。 那么當(dāng)我們考慮是否要把第K個正數(shù)加入到解向量中的時候,我們就能找到兩個條件組成這個限界函數(shù)了: (1) 這個公式的含義是:當(dāng)你考慮是否要把第K個正數(shù)加入到解向量的時候,不管你要加進(jìn)來或者是不打算把它加進(jìn)來,前K個解向量的和(包括第K個,當(dāng)然X(k)可能是0或者1),加上后面所有的數(shù)的和一定要大于等于M,否則你把剩下的數(shù)都加了進(jìn)來還比M小,這次的決策X(k)=0或者1肯定得不到滿足條件的解向量。所以也就沒有必要擴(kuò)展這個結(jié)點的左兒子或者右兒子了。 (2) 這個公式的含義是,當(dāng)你考慮是否要把第K個正數(shù)加入到解向量的時候,不管你要加進(jìn)來或者是不打算把它加進(jìn)來,提前往后看一步,判斷如果把第K+1個正數(shù)算進(jìn)來后的值大于M,就不把第K個正數(shù)加進(jìn)來。也就是說不生成第K-1個節(jié)點的兒子。 三.實驗要求 (1)用回溯法算法設(shè)計方法求解N元皇后問題; (2)找出N皇后問題的互不攻擊的所有解; (3)皇后數(shù)N由鍵盤動態(tài)輸入; (4)上機(jī)實現(xiàn)所設(shè)計的算法; (5)分析所設(shè)計的算法的時間/空間復(fù)雜性。 四.實驗過程設(shè)計(算法設(shè)計過程) (1)分析N皇后問題的約束條件,并將其顯示化,選擇存儲結(jié)構(gòu)建立相應(yīng)的數(shù)學(xué)模型; (2)根據(jù)所建立的數(shù)學(xué)模型,設(shè)計求解該問題的粗略算法; (3)對所設(shè)計的粗略算法求精,得具體算法; (4)在C/C++下實現(xiàn)所設(shè)計的算法; (5)分析運行結(jié)果的正確性; (6)進(jìn)行算法效率分析; (7)課后寫出實驗報告。 五.源代碼 (1) n皇后問題
- #include <iostream>
- using namespace std;
- const int N = 20;
-
- // bool數(shù)組用來判斷搜索的下一個位置是否可行
- // col列,dg對角線,udg反對角線
- // g[N][N]用來存路徑
- //count表示第幾個解
-
- int n;
- char g[N][N];
- bool col[N], dg[N], udg[N];
- int count = 0;
- void dfs(int u)
- {
- // u == n 表示已經(jīng)搜了n行,故輸出這條路徑
- if (u == n)
- {
- count++;
- cout<<"第"<<count<<"個解:"<<endl;
- for (int i = 0; i < n; i ++ ) cout << g[i] << endl;
- cout<<endl;
- return;
- }
-
- //對n個位置按行搜索
- for (int i = 0; i < n; i ++ )
- // 剪枝(對于不滿足要求的點,不再繼續(xù)往下搜索)
- //udg[n - u + i],+n是為了保證大于0
- if (!col[i] && !dg[u + i] && !udg[n - u + i])
- {
- g[u][i] = 'Q';
- col[i] = dg[u + i] = udg[n - u + i] = true;
- dfs(u + 1);
- // 恢復(fù)現(xiàn)場 這步很關(guān)鍵
- col[i] = dg[u + i] = udg[n - u + i] = false;
- g[u][i] = '.';
-
- }
- }
-
- int main()
- {
- cout<<"請問這是幾皇后問題:"<<endl;
- cin >> n;
- cout<<endl;
- for (int i = 0; i < n; i ++ )
- for (int j = 0; j < n; j ++ )
- g[i][j] = '.';
-
- dfs(0);
- return 0;
- }
復(fù)制代碼
運行結(jié)果:
(2) 子集和數(shù)問題
- #include <iostream>
- using namespace std;
-
- //求解函數(shù)
- void sumOfSub(float s, int k, float r, int *x, float m, float *w);
- void sumOfSub(int *x, int n, float m, float *w);
-
- int main()
- {
- int n; //n表示集合元素個數(shù)
- float m; //m表示目標(biāo)和
- cout << "請輸入集合元素個數(shù):";
- cin >> n;
- cout << "請輸入目標(biāo)和:";
- cin >> m;
- float *arr = new float [n + 1];
- int *x = new int [n + 1]; //求解狀態(tài)
- cout << "請輸入" << n <<"個集合元素(正值):";
- for(int i=0; i < n; i++)
- {
- cin >> arr[i];
- }
- cout << "可行解:\n";
- sumOfSub(x, n, m, arr);
-
- return 0;
- }
-
- void sumOfSub(float s, int k, float r, int *x, float m, float *w)
- {
- x[k] = 1;
- if(s + w[k] == m)//一個可行解
- {
- for(int j = 0;j <= k; j++)//兩種輸出方式任選
- {
- if(x[j] == 1) //完成輸出,輸出選取的元素
- cout << w[j] << " ";
- }
- cout << endl;
- }
- else if(s + w[k] + w[k+1] <= m)
- {
- sumOfSub(s+w[k], k+1, r-w[k], x, m, w);//搜索左子樹
- }
- if((s + r - w[k] >= m)&&(s + w[k]+1 <= m))
- {
- x[k] = 0;
- sumOfSub(s, k+1, r - w[k], x, m, w); //搜索右子樹
- }
- }
- void sumOfSub(int *x, int n, float m, float *w)
- {
- float r = 0;
- for(int i = 0; i < n; i++) r += w[i];//計算總值,判斷是否有解
- if(r >= m && w[0] <= m) sumOfSub(0, 0, r, x, m, w);
- }
復(fù)制代碼
運行結(jié)果:
完整的Word格式文檔51黑下載地址:
|
評分
-
查看全部評分
|