分治算法——乒乓球比赛日程问题

分治算法

  • 将一个计算复杂的问题分为若干个子问题来进行求解,然后综合各个小问题得到复杂问题的最终答案

    1. 分解:
      将原问题分解为若干规模较小的,相互独立,与原问题相同的子问题

    2. 解决:
      如果小问题容易解决就解决若干的子问题,不然就是继续解决第一个步骤,直到子问题可以解决

    3. 合并:
      将解决好的子问题的解合并为原问题的解

      有些问题是不需要合并子问题的解的,此时就不需要第三步了。

例题

  • 乒乓球比赛日程问题:
    问题:设有n名选手参赛,初赛进行n-1天,每位选手每一天必须比赛一次不轮空。

    • 分析:
      • 对于n位选手来说,这是一个复杂的计算,可以将它分解为较为小的子问题,比如说只有两个人参赛;
      • 解决两个人参赛的赛程,发现还是不足以分配,然后再分析4个人、8个人……等,直到问题得以解决
  • 解决:

#include<stdio.h>
#include<stdlib.h>
void schedule(int n,int m);
int check(int m);
int player[65][65] = {0};
int main()
{
	int m;	
	printf("输入参赛人数:");
	scanf("%d",&m);
	if(!check(m)){
		printf("输入的数必须是2的整数幂");
		return 0;
	}
	schedule(1,m);

	for(int i = 1;i <= m;i++){
		for(int j = 1;j <= m;j++){
			printf("%3d",player[i][j]);
		}
		printf("\n");
	}


}
void schedule(int n,int m)
{
	if(m == 2){	//达到最小可以解决的时候
		player[n][1] = n;
		player[n][2] = n+1;
		player[n+1][1] = n+1;
		player[n+1][2] = n;
	}else{
		schedule(n,m/2);//没到最小可以解决的时候就继续分解
		schedule(n + m/2,m/2);//这时候已经解决完了最小可解决问题,回来解决另一半的最小程度m
		//开始解决剩下的部分
        for(int i = n+m/2;i <= n+m; i++){
			for(int j = m/2 + 1;j <= m;j++){
				player[i][j] = player[i - m/2][j - m/2];
			}
		}
		
		for (int i = n; i < n + m/2; i++){
			for(int j = m/2 + 1;j <= m; j++){
				player[i][j] = player[i + m/2][j - m/2];
			}
		}
		
	}
}
int check(int m)
{
	int i = 2;
	int j = 2;
	for(int i;i < 8;i++){
		j *= 2;
		if(j == m)	break;
	}
	if(i >= 8){
		return 0;
	}
	return 1;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值