基本算法之分治算法

基本算法之分治算法

一.分治算法的基本思想

分治算法的基本思想是將一個計算複雜的問題分爲規模較小、計算簡單的小問題求解,然後綜合各個小問題,得到最終的答案。大致執行的流程如下:
1.對於一個規模爲N的問題,若該問題比較容易解決(比如規模N較小),則直接解決;否則執行下面的步驟。
2.將該問題分解爲M的個規模的小問題,這些子問題相互獨立,
並且與原問題的形式相同。
3.遞歸地解這些子問題
4.然後,將各個子問題的解合併得到原問題的解。
使用分治算法需要待求解問題能夠轉化爲若干個小規模的相同問題,通過逐步的劃分,能夠達到一個易於求解的階段而直接求解。然後,程序中可以使用遞歸算法來進行求解。

典型實例

一個袋子裏有10個硬幣,其中有一枚是假的,並且假幣和真幣一模一樣,肉眼很難分辨出來,目前知道假幣比真幣的重量輕一點。請問怎麼區分哪枚硬幣是假幣?
1.分析
採用遞歸分治算法的思想來解決這個問題,大致分析步驟如下:
1)首先爲每一枚硬幣編號,然後將所有的硬幣等分爲兩份,放在天平的兩邊。這樣就將區分10枚硬幣的問題,變爲區別兩堆硬幣的問題。
2)因爲假幣的重量輕,因此天平較輕的一側中一定包含假幣。
3)再將較輕的一側的硬幣等分爲兩份,重複上述的做法。
4)直到剩下兩枚硬幣,可用天平直接找出假幣。
2.參考代碼

import java.util.Scanner;

public class Divide_conquer {
	static final int maxnum=10;
	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) {
			for(i=low;i<=low+(high-low) / 2;i++) {
				sum1=sum1+coin[i];
			}
			for(i=low+(high-low) / 2;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 location;
		System.out.println("分治算法求假硬幣問題!");
		System.out.println("輸入硬幣的總的個數:");
		Scanner input = new Scanner(System.in);
		n=input.nextInt();
		System.out.println("請輸入硬幣的真假:");
		for(i=0;i<n;i++) {
			coin[i]=input.nextInt();
		}
		location=FalseCoin(coin, 0, n-1);
		System.out.println("在上述"+maxnum+"個硬幣中,第"+location+"個硬幣是假的!");
	}

}

3.結果展示
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章