各个击破的分治思想
定义:采用各个击破的方法,将一个规模为N的问题分解为K个规模较小的子问题
要求:每个小问题相互独立且与原问题性质相同
步骤:
1,分解,将要解决的问题划分为若干个规模较小的同类的问题
2,求解,将子问题进行用较简单的方法进行求解
3,合并,按照原问题要求,价格子问题解逐层合并
实战演练
public class TheCalanderOfGame {
//分治思想
//假设有8个队伍比赛,每个队伍每天只比一次,且每个队都要和其他队伍比赛一次,比赛n-1天
//则打印出比赛安排
//算法思想:n个队伍比赛由n/2个队伍决定,将这种一分为二的方法依次进行,直到只剩下2个队伍为止
static int length=64;
static Integer[][] a=new Integer[length+1][length+1];
public void gamecal(int k,int n){//第k个编号,共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{
gamecal(k,n/2);
gamecal(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=n/2+k;i<n+k;i++){//填充右下角
for (int j=n/2+1;j<=n;j++){
a[i][j]=a[i-n/2][j-n/2];
}
}
}
}
public static void main(String[] args) {
int n=0;
Scanner s=new Scanner(System.in);
System.out.print("请输入队伍数量:");
while (true){
Integer m=s.nextInt();
if (m/2.0==m/2 && m<=64){
n=m;
break;
}else {
System.out.println("输入有误!!!请输入数不超过64,且为偶数!");
continue;
}
}
TheCalanderOfGame tcog=new TheCalanderOfGame();
tcog.gamecal(1,n);
String str="";
for (int i=1;i<=n;i++){
if (i==1){
System.out.print("编号"+" ");
}
str="第"+i+"天";
System.out.print(str+" ");
}
System.out.println("\n");
for (int i=1;i<=n;i++){
for (int j=1;j<=n;j++){
System.out.print(a[i][j]+" ");
}
System.out.print("\n");
}
}
}
结果:输入 8
总结分治问题能解决的问题:
1,(解小性)当所有问题规模缩小到一定程度就容易解决问题,大多数都满足
2,(分同性)分解为若干个规模小的相同的问题,大多数问题都满足,且反应了递归的应用
3,(合并性)子问题解可以合并为该问题的解,这是决定能否利用分治的关键,若只满足1,2可以考虑贪婪或动态迭代
4,(独立性)子问题都是独立的,不涉及公共问题,若涉及,则考虑动态迭代更好