分治演算法:乒乓球比賽的日程安排
阿新 • • 發佈:2019-02-03
乒乓球比賽的日程安排
問題:
設有n位選手參賽,初賽進行n-1天,每位選手每天必須比賽一次,不能輪空。程式設計求解賽程安排。
分析:
1、求n位選手的賽程安排,可採用分治演算法的思想,將問題規模不斷縮小,比如縮小到8,4,2等規模大小;
2、分析2,4,8等小規模時的賽程安排:
分治演算法主要思想:
(1)、若原問題規模大小不便計算,將問題原本規模分解成若干個規模較小的相同問題;
(2)、每個子問題求解相互獨立,且與原問題形式相同,遞迴解這些子問題合併後組成原問題答案;
分治演算法適用問題:
(1)、問題可分解成若干個規模較小的相同問題;
(2)、合併子問題的解可以得到原問題的解;
(3)、各個子問題相互獨立;
分治演算法的主要步驟:
(1)、分解:縮小問題規模;
(2)、求解:足夠小的規模可用簡單方法求解;
(3)、合併:按照求解問題要求,合併子問題的解,構成最終的解;
程式碼實現:
#include <iostream>
#define max 64
int a[max+1][max+1] = {0};
void game_cal(int k, int n)
{
if (n == 2)
{
a[k][1] = k;
a[k][2] = k + 1;
a[k+1][1] = k+1;
a[k+1][2] = k;}
else
{
game_cal(k, n/2);
game_cal(k+n/2, n/2);
for (int i = k; i < k+n/2; ++i)
{
for (int j = n/2+1; j <= n; ++j)
a[i][j] = a[i+n/2][j-n/2];
}
for (int i = k+n/2; i < k+n; ++i)
{
for (int j = n/2+1; j <= n; ++j)a[i][j] = a[i-n/2][j-n/2];
}
}
}
int main()
{
int num;
std::cout << "enter the player numbers:" << std::endl;
std::cin >> num;
game_cal(1, num);
std::cout << " n ";
for (int i = 1; i < num; ++i)
std::cout << i << " ";
std::cout <<std::endl;
for (int i = 1; i <= num; ++i)
{
for (int j = 1; j <=num; ++j)
printf("%2d", a[i][j]);
std::cout << std::endl;
}
return 0;
}
答案截圖:
缺陷:
只能解決2的整數次冪資料輸入;
資料大小限制,不過可以在程式碼頭部,巨集定義部分修改;
*****
分治和遞迴的區別與聯絡:
遞迴:函式直接或者間接的呼叫自身;
遞迴是分治演算法在解決問題時可能用到的方法(當問題規模足夠簡單時直接計算即可);