约瑟夫环O(N)和O(M*N)算法详解

本文详细介绍了约瑟夫环问题,包括使用数组和链表模拟的O(n*m)方法,以及运用动态规划实现的O(n)解决方案。动态规划方法通过递推公式,揭示了n个人与n-1个人问题之间的关系,从而高效地找出最后出列者的编号,但无法得到出列顺序。
摘要由CSDN通过智能技术生成

问题描述:
已知n个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。从编号为1的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列,求最后一个出列人的编号。

该问题可以用数组或者循环链表模拟,因为都是直接模拟,需要循环n次,每次数m次,所以时间复杂度都是O(n*m)。虽然复杂度比O(n)大,但是可以求出出圈的编号顺序。也正是因为该方法将每次出圈的人都找了出来,所以做了很多无用操作,复杂度才会高达O(n*m)。
下面是数组和链表方法的代码:
题意:n个人,从第k个人开始数1,数到m的人剔除,输出剔除的顺序。

#include <iostream>
#include<cstdio>
#include<ctime>
#include<algorithm>
#include<cstdlib>
using namespace std;
#define MAXN 10000
int a[MAXN];
int N,k,m;
bool InCircle[MAXN];
typedef struct _node{
    struct _node* prev;
    struct _node* next;
    int number;
}node;
node* MakeDLL(int n){
    node *head = new node;/*Memory allocated to the head node*/
    node *tail;
    int i;
    head->next = head;
    head->prev = head;
    head->number = 1;
    tail =
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值