約瑟夫問題一般的解法即用迴圈模擬報數,但是此這樣的方法時間複雜度為o(mn),m為報的數,n為人數,在規模較大時旺旺效率並不好,我們可以用數學方法來講問題進行簡化,用o(n)的複雜度解決問題
初始的約瑟夫問題設為f(n),我們假設從第0人開始報數,第乙個出去的人即第m-1個人,淘汰一人之後我們可以看作是乙個n-1人的約瑟夫問題,但是其初始報數字置並不是從頭開始,而是從第m%n處開始,我們可以將序號平移,將m%n處的人移動到第一位,便可以變成一n-1人的約瑟夫環f(n-1),則f(n-1)中編號為k的人剛才的序號為(k+m)%n,
即f(n)[(k+m)%n]=f(n-1)[k]
類似的,我們反過來看,當只有乙個人時
f(1)=0
這個人即為最後勝利的人,那麼這個人在上一次報數中所在的位置為
f(2)=(f(1)+m)%n
f(3)=(f(2)+m)%n
f(n)=(f(n-1)+m)%
即為此人最開始的編號
c++實現如下
#includeusing namespace std;
int main(int argc, char** argv)
cout<
約瑟夫問題的數學解 C
約瑟夫問題一般的解法即用迴圈模擬報數,但是此這樣的方法時間複雜度為o mn m為報的數,n為人數,在規模較大時旺旺效率並不好,我們可以用數學方法來講問題進行簡化,用o n 的複雜度解決問題 初始的約瑟夫問題設為f n 我們假設從第0人開始報數,第乙個出去的人即第m 1個人,淘汰一人之後我們可以看作是...
約瑟夫問題的數學解法
我們用較為簡潔的語言描述一下約瑟夫問題 有n個人從0 n 1進行編號,然後進行0 m 1的報數,報數到m 1的人出列,然後從下乙個人繼續開始新一輪的報數,最後剩下乙個人為勝者。其實我們可以重新看待一下約瑟夫問題,當沒刪除乙個人之後,我們從這個人後面的那個人重新開始0 n 2的編號,然後刪除 m 1 ...
約瑟夫問題數學解法
寫完密碼約瑟夫就想到原來看到約瑟夫問題的乙個數學解法 很巧妙很簡單 不過只能推出最後乙個出列的人 無論是用鍊錶實現還是用陣列實現都有乙個共同點 要模擬整個遊戲過程,不僅程式寫起來比較煩,而且時間複雜度高達o nm 當n,m非常大 例如上百萬,上千萬 的時候,幾乎是沒有辦法在短時間內出結果的。我們注意...