C++之分治算法

C++之

分治算法篇

    分治算法的基本思想是将一个规模为N的问题分解为K个规模较小的子问题,这些子问题相互独立且与原问题性质相同。求出子问题的解,就可得到原问题的解。

基本思想:

    当我们求解某些问题时,由于这些问题要处理的数据相当多,或求解过程相当复杂,使得直接求解法在时间上相当长,或者根本无法直接求出。对于这类问题,我们往往先把它分解成几个子问题,找到求出这几个子问题的解法后,再找到合适的方法,把它们组合成求整个问题的解法。如果这些子问题还较大,难以解决,可以再把它们分成几个更小的子问题,以此类推,直至可以直接求出解为止。这就是分治策略的基本思想。一般情况下,还会用到二分法

二分法:

     利用分治策略求解时,所需时间取决于分解后子问题的个数、子问题的规模大小等因素,而二分法,由于其划分的简单和均匀的特点,是经常采用的一种有效的方法,例如二分法检索。

基本算法:

分治法解题的一般步骤:

(1)分解,将要解决的问题划分成若干规模较小的同类问题;
(2)求解,当子问题划分得足够小时,用较简单的方法解决;
(3)合并,按原问题的要求,将子问题的解逐层合并构成原问题的解
具体用法:
{//开始
if(1、问题不可分)2、返回问题解;
  else
  {
   3、从原问题中划分出含一半运算对象的子问题1;
 4、递归调用分治法过程,求出解1;
 5、从原问题中划出含另一半运算对象的子问题2;
 6、递归调用分治法过程,求出解2;
 7、将解1、解2组合成整个问题的解;
  }
}//结束
应用场景:
 运用分治策略解决的问题一般来说具有以下特点:
1、原问题可以分解为多个子问题
   这些子问题与原问题相比,只是问题的规模有所降低,其结构和求解方法与原问题相同或相似。
2、原问题在分解过程中,递归地求解子问题
   由于递归都必须有一个终止条件,因此,当分解后的子问题规模足够小时,应能够直接求解。
3、在求解并得到各个子问题的解后
应能够采用某种方式、方法合并或构造出原问题的解。
 
不难发现,在分治策略中,由于子问题与原问题在结构和解法上的相似性,用分治方法解决的问题,大都采用了递归的形式。在各种排序方法中,如归并排序、堆排序、快速排序等,都存在有分治的思想。

相关例题:

问:

设有n=2^k个运动员要进行网球循环赛。现要设计一个满足以下要求的比赛日程表:       

(1)每个选手必须与其他n-1个选手各赛一次;      (2)每个选手一天只能参赛一次;      (3)循环赛在n-1天内结束。

     请按此要求将比赛日程表设计成有n行和n-1列的一个表。在表中的第i行,第j列处填入第i个选手在第j天所遇到的选手。其中1≤i≤n,1≤j≤n-1。8个选手的比赛日程表如下图: 

解:

 

#include<iostream>

 

#include<cmath>

 

using namespace std;

 

#define MAXN 64

 

int calendar[MAXN + 1][MAXN];

 

void Round_Robin_Calendar()

 

{

 

int i,j,m,number,n,temp,t=0;

 

cout<<"输入选手个数:";

 

cin>>number;
n= 2;
calendar[1][1] = 1; calendar[1][2] = 2;

 

calendar[2][1] = 2; calendar[2][2] = 1;

 

 for(m=1;m < number;m++)
{
temp = n;
n=2*n;
for(i = temp + 1;i <= n;i++)
for(j = 1;j<= temp ;j++)
calendar[i][j] = calendar[i - temp][j] + temp;

 

for(i = 1;i <= temp;i++)
for(j = temp + 1;j <= n;j++)
calendar[i][j] = calendar[i + temp][(j +temp)%n];

 

for(i = temp+1;i<= n;i++)
for(j=temp+1;j<= n;j++)
calendar[i][j] =calendar[i-temp][j-temp];
}
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{ cout<<calendar[i][j]<<" ";

 

t++;

 

if(t%8==0)

 

cout<<endl;

 

}

 

}

 

int main(int argc, char* argv[])

 

{

 

Round_Robin_Calendar();

 

cout<<" 应用程序运行结束 ";

 

return 0;

 

}

 

 

 
济南稼轩学校
39级10班  续尧

 

 

 

  

posted on 2015-07-12 15:19  3910续尧  阅读(2392)  评论(0编辑  收藏  举报

导航