約瑟夫問題 遞歸解法

約瑟夫問題是個有名的問題:N個人圍成一圈,編號由0到N-1,從第一個開始報數,第K個將出局,最后剩下一個人。例如N=6,K=5,出局人編號的順序是:4,3,5,1,2,贏家是0。

這里給出一個十分簡潔的遞歸解法:

#include <bits/stdc++.h>
int solve(int n, int k) {
    if (n == 1) return 0;
    else return (solve(n - 1, k) + k) % n;
}
int main() {
    int N, K;
    scanf("%d %d", &N, &K);
    printf("%d", solve(N, K));
    return 0;
}

理解:
solve(n,k)的意思是,有n人,以k為步長刪人的約瑟夫問題的解。那么顯然solve(1,k)=0,即只有1個人的時候,勝者就是編號為0的這一個人。

若不是1個人,有n人,刪掉第k人(編號k-1)之后變成了n-1人,下次起始的地方是從這個出局的人后面開始算的,不妨把該開始位置的人編號“看成“0。
示意:

... [k-1 ] [ k ] [k+1] ...    // 刪之前 即“先狀態(tài)”
... [dele] [ 0 ] [ 1 ] ...    // 刪之后 即“后狀態(tài)”

那么若要從n-1個人的“后狀態(tài)”恢復到“先狀態(tài)”,其實所有人的編號相當于加k,亦即f[n] = f[n-1] + k,再由于是環(huán)的問題,所以加完再對"先狀態(tài)時,即刪前"人數n取模即可。

這里有個小地方要注意一下,每次取模的是當前游戲人數,可以稍微想想為啥?如果你寫成迭代版本,以i為下標迭代,F[1]=0;F[i]=(F[i-1]+k)%i;這里是模i而非n,要留意。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • “有問題”是生活的一大內容。 有了互聯網之后,生活上的各類問題,只要去找百度和Google就可以了。 而學習上遇到...
    月光畫畫閱讀 901評論 0 50
  • 生活是一件嚴肅的事
    北七海閱讀 191評論 0 0
  • 編者注:本文摘譯自Close.io公司網站博客,譯文有刪改。內容不當之處請在Kuick微信公眾號后臺留言,獲取更多...
    崔超閱讀 440評論 0 0
  • 玲子姐是我們那活力充沛的婦女之友之一,近四十歲仍舊風韻猶存,生性大大咧咧,到哪都能打成一片。雖說離異,獨自帶著兒子...
    獨立行走的魚閱讀 689評論 0 4
  • 如果說人是有靈性的,那么夢是不是也有感應?你走了一年半,是不是不放心你的兒子,你的孫子,才托夢給我? 你又一次出現...
    瞳瞳日中的微笑閱讀 950評論 1 3

友情鏈接更多精彩內容