动态规划解决约瑟夫环问题
来源:互联网 发布:百知java培训 编辑:程序博客网 时间:2024/04/28 08:18
题目:
约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号0,1,2,3…n-1分别表示)围坐在一张圆桌周围。从编号为0的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,求最后一个出列的人。
1.经典解法
可以用链表来模拟约瑟夫环,每次在链表中删除第m个节点,然后不断,直至链表中只剩下一个节点。最后一个这个节点就是我们要求的节点。
注意:当迭代器扫描到链表末尾时,将迭代器移至链表头。
int lastRemaining(unsigned int n, unsigned int m){ if(n<1||m<1) return -1; list<int> numbers; //单链表模拟约瑟夫环(Josephus Ring) for(int i=0;i<n;++i) numbers.push_back(i); list<int>::iterator cur=numbers.begin(); //从第一个节点开始报数 while(numbers.size()!=1){ //循环迭代至约瑟夫环只剩最后一个元素 for(int i=0;i<m-1;++i){ //迭代m-1次找到需要移出环的元素 ++cur; if(cur==numbers.end()) //迭代器扫描到链表末尾时,将迭代器移至链表头 cur=numbers.begin(); } list<int>::iterator next=++cur; if(next==numbers.end()) next=numbers.begin(); --cur; numbers.erase(cur); cur=next; } return *cur;}
分析:经典解法易于理解,实现简单。但是重复遍历降低效率,没删除一个元素需要m步移动,对n个元素,时间复杂度为O(mn)。
2.动态规划求解
动态规划重点是要确定状态和状态转移方程。状态就是确定问题的解的表达式,状态转移方程就是上一阶段问题的解推出当前阶段问题解的递推式。
针对约瑟夫环问题,n个元素的环可以定义为f(n,m),m表示每次移动的步数。则状态就是f(n,m)。那么对于n-1个元素的环,其最后一个被移除的元素就是f(n-1,m)。当环中只有一个元素时,f(1,m)=0。那么这里的重点和难点就是找出f(n,m)和f(n-1,m)之间的关系。也就是状态转移方程。
那么看如下分析:
(1)第一个被删除的数为 (m - 1) % n,设下标为k。
(2)假设第二轮的开始元素下标为k+1,那么这n - 1个数构成的约瑟夫环为k + 1, k + 2, k +3, …..,k - 3, k - 2,k-1。做一个简单的映射。
k+1 —> 0
k+2 —> 1
…
n-1 —> n-k-2
0 —> n-k-1
…
k-1 —>n-2
可见,映射关系为p(x)=(x-k-1)%n,那么其从右到左的映射关系是
有了状态转移方程,我们可以使用迭代或者递归来完成问题求解。建议迭代,以免对不同阶段的问题重复求解。
下面以迭代方式实现:
int lastRemainingDP(unsigned int n, unsigned int m){ if(n<1||m<1) return -1; int last=0; //n=1,最后移出环的元素 for(int i=2;i<=n;++i) last=(last+m)%i; return last;}
参考文献
[1]剑指Offer.何海涛.电子工业出版社.
[2]解题笔记(10)——约瑟夫环问题.
- 动态规划解决约瑟夫环问题
- 动态规划解决约瑟夫环问题
- 约瑟夫问题(动态规划解法)
- 动态规划解决装载问题
- 动态规划解决背包问题
- 动态规划解决skiing问题
- 动态规划解决经典问题
- 动态规划解决背包问题
- TSP问题动态规划解决
- 动态规划解决背包问题
- 动态规划解决硬币问题
- 动态规划解决迷宫问题
- 动态规划解决迷宫问题
- 程序员面试金典(动态规划):约瑟夫环问题(java解法)
- 解决下约瑟夫环问题
- 数组解决约瑟夫环问题
- 数组解决约瑟夫环问题
- 约瑟夫环问题的解决
- vim安装YouCompleteMe插件,与python补全插件jedi-vim
- DataGridView显示数据之方法一
- javascript中希望定义一个页面刷新也不能改变其值的方法
- CodeForces 610A Pasha and Stick (水)
- CortexM0开发 —— LPC11C14的UART使用方法
- 动态规划解决约瑟夫环问题
- iperf命令
- jQuery
- queue,priority_queue
- C语言typedef的用法
- HDU 4813-Hard Code-字符串
- android layout,measure,draw资料收集
- java事务学习笔记(八)--分布式事务入门例子(Spring+JTA+Atomikos+Hibernate+JMS)
- GCD 小结