C++ 新約瑟夫問題

來源:互聯網
上載者:User

標籤:過程   組織   條件   重複   輸入   計算   ==   約瑟夫問題   c++   

#include<iostream>#include<cmath>using namespace std;int main(){    int n,sum=0,j,i,k,lpl,a[100000],b[100000];    cin>>n;    a[1]=1,b[1]=1;            for(int i=2;i<=n;i++)    {            a[i]=(a[i-1]+1)%i+1;    if(a[i]==i)b[i]=i;    else b[i]=b[a[i]];    }    cout<<b[n]+n; }

又是一道遞推  代碼如上;

試題描述:

你一定聽說過經典“約瑟夫”問題吧?現在來組織一個皆大歡喜的新遊戲:假設 n 個人站成一圈,從第 1 人開始交替的去掉遊戲者,但只是暫時去掉(例如,首先去掉 2),直到最後剩下唯一的倖存者為止。倖存者選出後,所有比倖存者號碼高的人每人將得到 1 塊錢,並且永久性地離開,其餘剩下的人將重複以上過程,比倖存者號碼高的人每人將得到 1 塊錢後離開。一旦經過這樣的過程後,人數不再減少,最後剩下的那些人將得到 2 塊錢。請計算一下召集人一共要付出多少錢?

例如,第一輪有 5 人,倖存者是 3,所以 4、5 得到 1 塊錢後離開,下一輪倖存者仍然是 3,因此沒有人離開,所以每人得到 2 塊錢,總共要付出 2+2*3=8 塊錢。

輸入:

一行一個整數 n。

輸出:

一行一個整數,不超過65535,表示總共要付出多少錢。

輸入執行個體:

10

輸出執行個體:

13

 

首先,每個人都會得到1塊錢,只有最後的那些倖存者多得到了1塊錢。所以只要求出最後會倖存的人即可。

假設經過m次出圈操作後還剩final(m)個人,此時的人數已經不可以再減少了,則問題的解應該為final(m)+n.可是如何求final(m)呢?

當第i次的final(i)=i時,人數就不會再減少了,此時的i即為m,否則,就需要對剩下的final(i)個人再進行報數出圈操作;

會有兩種情況:1 設jose(i)為倖存者的編號,設報道K的人出去,則jose(i-1)可以理解為第一輪第一次報數,k出去後的狀態,k出去後會從k+1繼續報數,此時圈中有i-1個人,從k+1開始報數,編號jose(i)為:k+1,K+2......i,1,2.....,k-1;

                          2 可以人為地把這個圈逆時針轉k個單位,此時報數的編號jose(i-1):1,2.....,i-k,i-k+1,i-k+2....,i-1;

從上面兩種情況可以發現除了i和i-k以外,其他所有資料都滿足規律:jose(i)=(jose(i-1)+k)mod i。對這個式子稍微調整一下,變成的公式都滿足了:jose(i)=(jose(i-1)+1)mod i+1;

至此這個問題的遞推公式就出來了,邊界條件為jose(1)=1.然後,順推求出每個jose(i),直到某一次jose(i)=i,則final(i)=i,否則final(i)=final(jose(i)).

所以就是這樣了!!!

C++ 新約瑟夫問題

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.