循环日程安排问题(分治法)

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

例题分析:
设有n=2^k个选手要进行网球循环赛,要求设计一个满足以下要求的比赛日程表:
(1)每个选手必须与其他n-1个选手各赛一次;
(2)每个选手一天只能比赛一次;
(3)循环赛一共进行n-1天.
相关复杂度:
在该题中用T(k)表示2个选手网球循环赛问题的求解时间,有:
T(k)=1, 当k=1
T(k)=4T(k-1). 当k>1
求得T(k)=O(4^k)

[1] 李春葆.算法设计与分析(第二版)[M]. 北京:清华大学出版社,2018(2023年重印).

输入式样:
3

输出式样:
1 2 3 4 5 6 7 8
2 1 4 3 6 5 8 7
3 4 1 2 7 8 5 6
4 3 2 1 8 7 6 5
5 6 7 8 1 2 3 4
6 5 8 7 2 1 4 3
7 8 5 6 3 4 1 2
8 7 6 5 4 3 2 1

#include <stdio.h>
# define MAX 101
int k;
int a [MAX][MAX]; 
void Plan(int k)
{
   int i,j,n,t,temp;
   n=2; 
   a[1][1]=1;
   a[1][2]=2; 
   a[2][1]=2;
   a[2][2]=1;
for(t=1;t<=k;t++) 
{
  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+temp][(j+temp)% n];
for (i=temp+1;i<=n;i++) 
     for(j=temp+1;j<=n;j++)
a[i][j]=a[i-temp][j-temp];
   }
}
void main()
{
     scanf("%d",&k);
    int n=1<<k; 
      Plan(k); 
  for(int i=1;i<=n; i++)
  {
     for(int j=1;j<=n;j++)
        printf("%4d",a[i] [j]);
        printf("\n");
   }
}```

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TEP-All

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值