约瑟夫问题(动态规划解法)

约瑟夫问题:动态规划解决方案
博客介绍了约瑟夫问题的动态规划求解方法,通过分析不同循环次数下的规律,得出公式,并利用该公式通过循环计算出最终答案,提高了效率,避免了m*n的复杂度,展示了算法的魅力。

Josephus problem solution with o(n)

1.Description

People are standing in a circle waiting to be executed. Counting begins at a specified point in the circle and proceeds around the circle in a specified direction. After a specified number of people are skipped, the next person is executed. The procedure is repeated with the remaining people, starting with the next person, going in the same direction and skipping the same number of people, until only one person remains, and is freed.

2.Introduction

We have seen this kind of problems before. You can stimulate the whole process to get the answer you want. But its time cost is large, which holds a m*n complexity. This method can be accepted when n and m are accepted small, but fail to handle those situations when n or m is quite large. Thus, today let’s introduce a new method with a complexity of o(n).

3.Dynamic planning

To find the formula to solve this problem, we need to go through several loops to get the inner principle.
Suppose we have n people initially, and the m th person will be executed.
when loop=1, undoubtedly, the (m-1)%n th person will be executed.
when loop=2, let’s see the current situation:
the people list become:
m,m+1,...,n-2,n-1,0,1,2,...,m-2
it will be convenience for us if we map the list above to a new list like this
0,1,2,3,...,n-3,n-2
the map looks like this:

m   -> 0  
m+1 -> 1  
...  
...  
k-3 -> n-3  
k-2 -> n-2  

the map here can be summarized as f(x)=(x-m)%n.
Now, let’s define an expression to represent our final answer: f(n,m).Then, it’s common sense that f(1,m)=0. The main problem is to find the relationship between f(1,m) and f(n,m). How can we think?
If we can find the relationship between f(n,m) and f(n-1,m), then we can repeatedly use this relationship to find the relationship between f(n,m) and f(1,m).
As I mentioned above, we use a map from f(n) to f(n-1). Now, we can map it back, then we get what we want:
f(n,m)=(f(n-1,m)+m)%n
Now we can use this formula to get the final answer using a for loop.

4.Code

#include <iostream>
using namespace std;
int main(void){
    int n,m;
    int answer=0;           //we initial answer equals to 0 because for the last f(1,m)=0
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        answer=(answer+m)%i;
    }
    cout<<answer<<endl;
}

You can see this code is incredible simple but much faster than just stimulating the whole process. And that’s charm of algorithm, I think.

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值