用递归与分治策略求解网球循环赛日程表_算法设计:分治法(比赛日程安排)...
一、算法思路
1、思路
分治算法的思想是:對于一個規模位N的問題,若該問題可以容易解決(比如規模N較小),則直接解決,否則將其分解為M個規模較小的子問題,這些子問題互相獨立,并且與原問題形式相同,遞歸的解決這些子問題,然后將各子問題的解合并得到原問題的解
2、分治法適用范圍
一般具有以下特征的問題可以使用分治算法求解:
(1)求解問題可以分解為若干個規模較小的相同問題
(2)求解問題的規模分解到一定程度,就能夠很容易地求解
(3)合并子問題的解可以得到問題的解
(4)由求解問題所分解的各個子問題是互相獨立的
3、分治法的步驟
(1)分解:將要求解的問題劃分為規模較小的同類問題
(2)求解:當子問題劃分的足夠小的時候,用比較簡單的方法求解,得到子問題的解
(3)合并:按求解問題的要求,將子問題的解逐層合并,即可構成最終的解
二、分治法實例:比賽日程的安排
1、問題描述
某學校舉行乒乓球比賽,在初賽階段設置為循環賽,設有n位選手參賽,初賽共進行n-1天,每位選手要與其他每一位選手進行一場比賽,然后按積分排名選拔進入決賽的選手。根據學校作息時間,要求每位選手每天必須比賽一場,不能輪空。按此要求為比賽安排具體日程,即決定每天各選手對陣的對手
2、分析
設有n=2^k個選手參加循環賽,那么需要要求設計一個滿足以下要求比賽日程表:
1)每個選手必須與其它n-1個選手各賽一次;
2)每個選手一天只能賽一次
3、圖解
(1)2個選手的情況
如果只有兩個選手,那么第0列看作選手編號(我們從0開始對列編號,我們的第0列可以看作每個選手第0天在和自己打),第1列就是在第一天,每個選手要比賽的選手號
(2)如果選手的個數為2^2=4,那么日程安排如下圖
如果有4個選手,分別設計4/2=2個選手的比賽日程表,1-2選手前一天的比賽日程表如上圖表格左上角的深藍色子表格部分,3-4選手前一天的比賽日程表如上圖表格左下角的子表格。據此,后兩天的日程表可以將左上角的子表按其對應位置抄到右下角的子表,左下角的子表可以按其對應位置抄到右上角的子表。(同時,我們注意到,這是表的行列均為參賽選手數2^2 = 4,在用分治法求行、列均為(2^2)/2的長度的子表時,首先確定左上角的子表,左下角的子表可以由左上角的子表加(2^2)/2得到)
(3)如果選手的個數為2^3=8,那么日程安排表如下:
選手人數為8時,左上角的子表是選手1至選手4的前三天的比賽日程,左下角是選手5至選手8前三天的比賽日程。據此后四天的比賽日程,就是分別將左上角子表按其對應位置抄到右下角,將左下角的子表按其對應位置抄到右上角。這樣就完成了比賽日程的安排
這種解法是把求解2^k個選手的比賽日程問題劃分為2^1,2^2,......,2^k個選手的比賽日程問題。也就是說,要求2^k個選手的比賽日程,就要分為兩部分,分別求出2^(k-1)個選手的比賽日程,然后再進行合并。當然,這種解法只能求選手個數是2的次冪的情況
在每次迭代求解的過程中,可以看作4部分:
1)求左上角子表:左上角子表是前2^(k-1)個選手的比賽前半程的比賽日程。
2)求左下角子表:左下角子表是剩余的2^(k-1)個選手的比賽前半程比賽日程。這個子表和左上角子表的對應關系是,對應元素等于左上角子表對應元素加2^(k-1)。
3)求右上角子表:等于左下角子表的對應元素
4)求右下角子表:等于左上角子表的對應元素
代碼實現如下:
#include
#include
int main(void)
{
int a[9][9];
int x,y,i,j,t;
for(x=0;x<9;x++){
for(y=0;y<9;y++){
a[x][y]=0;
}
}
int n=2;
a[1][1]=1;
a[1][2]=2;
a[2][1]=2;
a[2][2]=1;
for(t=1;t<3;t++){
/*使用分治法填充日程表*/
int temp=n;
n=n*2;
/*擴展左下角*/
for(i=temp+1;i<=n;i++)
for(j=1;j<=temp;j++)
a[i][j]=a[i-temp][j]+temp;
/*擴展右上角*/
for(i=1;i<=temp;i++)
for(j=temp+1;j<=n;j++)
a[i][j]=a[i][j-temp]+temp;
/*擴展右下角*/
for(i=temp+1;i<=n;i++){
for(j=temp+1;j<=n;j++)
a[i][j]=a[i-temp][j-temp];
}
}
//打印結果
for(i=0;i<9;i++){
for(j=0;j<9;j++){
printf("%d ",a[i][j]);
}
printf("");
}
return 0;
}
總結
以上是生活随笔為你收集整理的用递归与分治策略求解网球循环赛日程表_算法设计:分治法(比赛日程安排)...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: http通道连接mysql_通过http
- 下一篇: linux进入mongodb数据库命令,