演算法分析與設計之減治法遞迴實現約瑟夫斯問題

2021-10-05 13:03:37 字數 1416 閱讀 5679

問題描述:

一共有n個人圍成一圈,編號從1到n,從第乙個開始喊號,只喊(一、二),喊到二的人出圈,直到只剩下1個人為止,求此人的最開始時的編號。

基本思想:

分為奇數和偶數來討論。

當n為偶數,如n = 6 時,初始位置為3的人,第二輪會在位置2;初始位置為5的人,第二輪會在位置3.以此類推,從大量的資料中可以推導出一定的規律,如下:

ysf(2k) = 2*ysf(k)-1
注意:其中 n = 2k , k 和2k均為問題的規模 ysf(k) 指 現在的位置 ,ysf(2k) 指 與現在位置比較的前乙個原位置。

例如:n = 6,則ysf(6) = 2*ysf(3)-1 ---->意思是問題規模從6 —>3的減治,而當k = 3是奇數,這就與我們下面討論的奇數情況聯絡。

讓我們來看看奇數的情況吧

2、如果n為奇數,則在第一輪所有偶數字上的人都被消去,如果我們把緊接著的位置1上的人也加進來,也就是說,在第一輪就剩下了n/2個人 ,在許多例子中,我們也可以得出規律:

ysf(2k+1)  = 2*ysf(k)+1
注意:其中 n = 2k+1 , k 和2k+1均為問題的規模 ysf(k) 指 現在的位置 ,ysf(2k+1) 指 與現在位置比較的前乙個原位置。

例如:之前偶數情況下的,當 n = 3時,ysf(3) = 2*ysf(1)+1; 意思是規模從3——>1的減治,而規模1就是遞迴的終點,當只有乙個人時,倖存者的最初編號就是1。

結合上面兩種情況,可以將n = 6 的遞迴情況羅列出來

ysf(6) = 2 *ysf(3)- 1 = 2 *( 2 * ysf(1) + 1 )- 1

——>ysf(1) = 1 所以 代入上式:ysf(3) = 3 從而ysf(6) = 5

喜大普奔,最終的倖存者的原始編號就是 5 !!!!

給出簡易的**:

#include

using

namespace std;

intysf

(int n)

else

if(n %2==

0)else

if(n%2==

1)}int

main()

執行結果:

減治法演算法設計

首先要申明的是減治法思想並不等同於分治法思想,減治法技術利用乙個問題給定例項的解和同樣問題較小例項的解之間的某種關係。一旦建立了這種關係,就可以從頂至下 遞迴 或者從底之上 迭代 地來運用該關係。減治法有3種主要的變種 1 減去乙個常量 2 減去乙個常量因子,大多數問題中常量因子為2 3 減去的規模...

資料結構與演算法(5)減治法

減治法 reduceandconquermethod 在將原問題分解為若干個子問題後,利用了原問題的解與子問題的解之間的關係,這種關係通常表現為 1 原問題的解只存在於其中乙個較小規模的子問題中 2 原問題的解與其中乙個較小規模的解之間存在某種對應關係。由於原問題的解與較小規模的子問題的解之間存在這...

演算法設計與分析之蠻力法

蠻力法是指採用遍歷 掃瞄 技術,即採用一定的策略將待求解問題的所有元素依次處理一次,從而找出問題的解。依次處理所有元素是蠻力法的關鍵,為了避免陷入重複試探,應保證處理過的元素不再被處理。1 蠻力法 列舉法 窮舉法 暴力法 要求設計者找出所有可能的情況,然後選擇其中一種情況,若該情況不可行 或不是最優...