分治算法兵乓球比赛日程(java)

分治算法之兵乓球比赛日程

    分治算法的基本思想是将一个规模为N的问题分解为K个规模较小的子问题,这些子问题相互独立且与原问题性质相同。求出子问题的解,就可得到原问题的解。也就是字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。这个技巧是很多高效算法的基础,如排序算法(快速排序,归并排序),傅立叶变换(快速傅立叶变换)

   问题的规模越小,越容易直接求解,解题所需的计算时间也越少。任何一个可以用计算机求解的问题所需的计算时间都与其规模有关。例如,对于n个元素的排序问题,当n=1时,不需任何计算。n=2时,只要作一次比较即可排好序。n=3时只要作3次比较即可,…。而当n较大时,问题就不那么容易处理了。要想直接解决一个规模较大的问题,有时是相当困难的。

基本思想

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

分治策略是:对于一个规模为n的问题,若该问题可以容易地解决(比如说规模n较小)则直接解决,否则将其分解为k个规模较小的子问题,这些子问题互相独立且与原问题形式相同,递归地解这些子问题,然后将各子问题的解合并得到原问题的解。这种算法设计策略叫做分治法。

   如果原问题可分割成k个子问题,1<k≤n,且这些子问题都可解并可利用这些子问题的解求出原问题的解,那么这种分治法就是可行的。由分治法产生的子问题往往是原问题的较小模式,这就为使用递归技术提供了方便。在这种情况下,反复应用分治手段,可以使子问题与原问题类型一致而其规模却不断缩小,最终使子问题缩小到很容易直接求出其解。这自然导致递归过程的产生。分治与递归像一对孪生兄弟,经常同时应用在算法设计之中,并由此产生许多高效算法。

package 练习;

import java.util.Scanner;

public class 分治算法兵乓球比赛日程 {
    public static int MAX=65;
    public static int a[][]=new int [MAX][MAX];
    public static void main(String[] args) {
        int i;
        System.out.println("请输入比赛选手人数");
        Scanner scanner=new Scanner(System.in);
        int people = scanner.nextInt();
        if(people/64>1||people%2!=0){
            System.out.println("输入的人数必须是2的整数次幂,且人数不超过64人!");
            return ;
        }
gemecal(1,people);
System.out.print("编号:");
for(i=1;i<people;i++){
    System.out.print("  "+i+"天");
}
System.out.println();
for(int j=1;j<=people;j++){
    for(int  n=1;n<=people;n++){
        System.out.print("  "+a[j][n]);
        
        
    }
    System.out.println();
}
    }

    public static void gemecal(int k, int people) {
        // TODO Auto-generated method stub
        int i,j;
        if(people==2){
            a[k][1]=k;
            a[k][2]=k+1;
//            a[K+1][1]=k+1;
            a[k+1][1]=k+1;
            a[k+1][2]=k;
        }
        else{
            gemecal(k, people/2);
            gemecal(k+people/2, people/2);
            for(i=k;i<k+people/2;i++){
                for(j=people/2+1;j<=people;j++){
                    a[i][j]=a[i+people/2][j-people/2];
                }
            }
            for(i=k+people/2;i<k+people;i++){
                for(j=people/2+1;j<=people;j++){
                    a[i][j]=a[i-people/2][j-people/2];
                }
            }
            
        }
    }

}

 结果:

请输入比赛选手人数
8
编号: 1天 2天 3天 4天 5天 6天 7天
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

posted @ 2016-03-16 22:51  哎呦喂小农漂亮  阅读(568)  评论(0编辑  收藏  举报