分治思想:将一个计算复杂的问题分为规模较小、计算简单的小问题求解,然后综合各个小问题,得到最终问题的答案。
执行步骤:
(1)对于一个规模为N的问题,若该问题比较容易解决,则直接解决;否则执行下面的步骤。
(2)将该问题分解为M个规模较小的字问题,这些子问题互相独立,并且与原问题形式相同。
(3)递归地解决这些子问题。
(4)然后,将各子问题的解合并得到原问题的解。
举例:
从30个硬币中找出假币,假币质量轻。
思路:
将硬币分为2份,较轻的一份含有假币,再分为2分。。。
代码实现:
import java.util.Scanner;
public class P3_4 {
static final int MAXNUM=30;
static int FalseCoin(int coin[],int low,int high) //算法
{
int i,sum1,sum2,sum3;
int re=0;
sum1=sum2=sum3=0;
if(low+1==high)
{
if(coin[low]<coin[high])
{
re=low+1;
return re;
}
else
{
re=high+1;
return re;
}
}
if((high-low+1)%2 == 0) //n是偶数
{
for(i=low;i<=low+(high-low)/2;i++)
{
sum1= sum1 + coin[i]; //前半段和
}
for(i=low+(high-low)/2+1;i<=high;i++)
{
sum2 = sum2 + coin[i]; //后半段和
}
if(sum1>sum2)
{
re=FalseCoin(coin,low+(high-low)/2+1,high);
return re;
}
else if(sum1<sum2)
{
re=FalseCoin(coin,low,low+(high-low)/2);
return re;
}
else
{
}
}
else
{
for(i=low;i<=low+(high-low)/2-1;i++)
{
sum1= sum1 + coin[i]; //前半段和
}
for(i=low+(high-low)/2+1;i<=high;i++)
{
sum2 = sum2 + coin[i]; //后半段和
}
sum3 = coin[low+(high-low)/2];
if(sum1>sum2)
{
re=FalseCoin(coin,low+(high-low)/2+1,high);
return re;
}
else if(sum1<sum2)
{
re=FalseCoin(coin,low,low+(high-low)/2-1);
return re;
}
else
{
}
if(sum1+sum3 == sum2+sum3)
{
re=low+(high-low)/2+1;
return re;
}
}
return re;
}
public static void main(String[] args) {
int[] coin=new int[MAXNUM];
int i,n;
int weizhi;
System.out.println("分治算法求解假银币问题!");
System.out.print("请输入银币总的个数:");
Scanner input=new Scanner(System.in);
n=input.nextInt(); //银币总的个数
System.out.print("请输入银币的真假:");
for(i=0;i<n;i++)
{
coin[i]=input.nextInt(); //输入银币的真假
}
weizhi=FalseCoin(coin,0,n-1); //求解
System.out.println("在上述"+MAXNUM+"个银币中,第"+weizhi+"个银币是假的!");
}
}
运行结果:
分治算法求解假银币问题!
请输入银币总的个数:30
请输入银币的真假:2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
在上述30个银币中,第11个银币是假的!