约瑟夫问题递推法

Posted by Hao Blog on September 2, 2024

约瑟夫问题递推法

模拟的时间开销太大 不得不回头考虑递推关系:

  • 将编号改为从0开始,记f(n,m)为原问题的解
  • 由于第一次遍历了0~(m-1)%n,则第二次遍历相当于将整个队伍循环左移了k位(k=m%n)
  • 所以子问题f(n-1,m)的解循环右移k位即为原问题的解f(n,m)
  • f(n,m)=(f(n-1,m)+m)%n
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include<cstdio>
using namespace std;
int getLive(int i,int m){
    if(i==1) return 0;
    return (getLive(i-1,m)+m)%i;
}
int main() {
    int n,m;
    scanf("%d %d",&n,&m);
    printf("%d\n",getLive(n,m)+1);
    return 0;
}
// 64 位输出请用 printf("%lld")