約瑟夫環 數學解法 f(n,k)=(f(n-1,k)+k)%n 公式講解


問題:有n個人站成環 從1開始報數,報k的人去死,之后下一個人報1,問當你是第幾個的時候可以活下來?

這篇文章主要是講解  f(n,k)=(f(n-1,k)+k)%n 這個公式是什么意思為什么是對的

 

雖然公式是使用數學解法 但開始時我會手動的模擬過程 其是有意義的 十分有助於理解 

首先我們看樣一個問題

n=2, k=3

a b

我們首先使用人力來數 a b a 很好 a死

接下來在試一遍 n=2 k=4

a b 

人力:a b a b 很好b死

n=2 k=5

人力 a b a b a 很好a死

n=2 k=9999999

人力:T_T

對於   a b 數到k死 其實用k%2就可以很快的知道誰會死了

為什么?

a b

設k=9 ab一共有兩個  所以 9%2=1  意思就是abab的數,數完最后一次完整的循環后又數了1個(數到了a)  這正是取模%的意義  

現在我們還是用手動模擬 n=11 k=3

這次不用字母而是用數字編號以直接返回生存者的編號(劇透 注意分別 第幾個和編號的不同)

1 2  3 4 5 6 7  8 9 10 11

第1個死去的 k%n 即 3%11=3 第三個死去 因為我們從死去的下一個開始重新數1 也就是說 死去的下個(編號4)是新的環的開始 死去的上個(編號3)是新的環的結束

4 5 6 7 8 9 10 11 1 2 (這就是新的環)

規則就是這樣 下面我會直接寫到生存者出現

 

1 2 3 4 5 6 7 8 9 10 11
4 5 6 7 8 9 10 11 1 2  
7 8 9 10 11 1 2 4 5    
10 11 1 2 4 5 7 8      
2 4 5 7 8 10 11        
7 8 10 11 2 4          
11 2 4 7 8            
7 8 11 2              
2 7 8                
2 7                  
7                    

當當最后的幸存者是7

------完結撒花------

 

f(n,k)=(f(n-1,k)+k)%n這個公式到底描述的是什么呢?(怎么用?)

將上面表格的每一行看成數組 這個公式描述的是下一輪幸存者在這一輪的下標位置

f(n,k)求得值是 有n個人 數k死最后幸存的人的下標位置是幾

這很明顯是個遞歸的式子 需要從底到上的運算 

最底端是 f(1,k) f(1,k)=0 就是說只有一個人的時候幸存者的下標是0(廢話--) 編號是7 

向上

f(2,k) =(f(1,k)+k)%n  在n=11 k=3是 f(2,3)=(f(1,3)+3)%2=3%2=1

在只剩兩個人時 幸存者在這一輪數組中的下標位置是1  (看看上面的表格 下標位置為1 編號是7 )

向上

f(3,3)=(f(2,3)+3)%3=4%3=1

在只剩三個人時 幸存者在這一輪數組中的下標位置是1  (看看上面的表格 下標位置為1 編號是7 )

f(4,3)=(f(3,3)+3)%4=4%4=0

在只剩三個人時 幸存者在這一輪數組中的下標位置是0  (看看上面的表格 下標位置為0 編號是7 )

.

.

f(11,3)=(f(10,3)+3)%11=6%11=6  (看看上面的表格第一行 下標位置為6 編號是7 )

我們很容易可以根據式子寫

1 int p=0;//結果 
2 for(int i=2;i<=n;i++)
3 { 
4     p=(p+k)%i; 
5 }

p就是我們要求的第一輪的生存者的下標  

而在第一輪中沒有人死去(淚目..) 編號與下標的關系是編號=下標+1(數組從0開始存儲)

所以完整的函數代碼是

int cir(int n,int k)
{
    int p=0;
    for(int i=2;i<=n;i++)
    {
        p=(p+k)%i;
    }
    return p+1;
}

那么這個公式為什么是正確的呢?

當我們殺死一個一個人 並形成一個新環時 實質上是掉這個人並把整個環向前移動k位

 

 

1 2 3 4 5 6 7 8 9 10 11

   第一輪去掉3

1 2 4 5 6 7 8 9 10 11  

們從死去的下一個開始重新數1 也就是說 死去的下個(編號4)是新的環的開始 死去的上個(編號3)是新的環的結束 就是把編號4前移k(3)格使他成為新環開始

 

 

                  1 2 3 4 5 6 7 8 9 10 11
            1 2 3 4 5 6 7 8 9 10 11 1 2 3
                                       

讓我們在重申一遍f(n,k)=(f(n-1,k)+k)%n描述的是下標位置的變化 

編號1的下標位置是0 0前移3格 下標位置變成-3 -3+11=8 所以在n輪下標位置為0的編號1在n-1輪中的下標位置變成了8

如果也有一個公式的話大概就是 f(n-1,k)=f(n,k)-k>=0?f(n,k)-k:f(n,k)-k+n; 

那么從n-1輪的下標位置推算第n輪的下標位置就很清楚了 f(n,k)=f(n-1,k)+k>=n?f(n-1,k)+k%n:f(n-1,k)+k  (%n  使得f(n,k)取得的下標在n的范圍之內)

f(n,k)=(f(n-1,k)+k)%n

 

以上

重點在於f(n,k)描述的是下標位置的變化

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM