Deeply understand the mathematical optimization method of Joseph ring

  • 2020-04-01 23:46:13
  • OfStack

Firstly, the mathematical optimization method of Joseph ring is as follows:
Problem description: n individuals (no. 0~(n-1)), count from 0, report (m-1) exit, the remaining people continue to count from 0. Find the number of the winner.
We know that after the first person (the number must be (m-1)%n) leaves the column, the remaining n-1 people form a new Joseph ring (starting with the number k=m%n) :     K + 1 k + 2 k... N minus 2, n minus 1, 0, 1, 2... K minus 2 and start at k with 0. Now let's switch their Numbers:
K - > 0 - k + 1 > 1 k + 2 - > 2
- n - 1 > N - 1 - k         0 - > N - k.    
              . .
K - 3 - > N - 3-2 - k > N - 2
Sequence 1:1, 2, 3, 4... N, n - 2, n - 1,
Sequence 2:1, 2, 3, 4... K - 1, k + 1,... N, n - 2, n - 1,
Sequence 3: k+1, k+2, k+3... N minus 2, n minus 1, n, 1, 2, 3... , k - 1-2 k
Sequence 4:1, 2, 3, 4... Five, six, seven, eight... , n - 2, n - 1
If we know the solution to this subproblem: for example, x is the winner, wouldn't changing this x back from the table above be exactly the solution for n people? !!!!! The formula for changing back is very simple, which I believe you can deduce:
∵ k = m % n;
X '= x+k = x+ m%n; And x plus m%n could be greater than n
X '= (x+m %n)%n =(x+m)%n =(x+m)%n = x'= (x+m)%n
How do we know the solution to the problem of n minus 1 personal Numbers? Yeah, we just need to know the individual solution to n minus 2. What's the personal solution to n minus 2? Of course, the n minus 3 case -- this is obviously a backwardation problem! Ok, so here's the idea. Here's the formula for recursion:
Let f indicate that I individual play the game and m exit the last winner's number, the final result is naturally f [n].
Recurrence formula: f[1]=0; [I] = f (f [I - 1) + m) % I; (I > 1)
The complete implementation code is as follows:


#include "stdio.h"
#include "stdlib.h"
int main(void)
{
 int n, m,i, f[20]={0};
 scanf("%d %d",&n,&m);
    for(i=2;i<=n;i++)
 {
  f[i]=(f[i-1]+m)%i;
  printf("%d Personal report, report %d The final winner subscript is %dn", i,m,f[i]);
 }
    printf("The winner is %dn", f[n]+1);
 system("pause");
}

The optimized code is:

#include "stdio.h"
#include "stdlib.h"
int main(void)
{
    int n, m,i, s=0;
 scanf("%d %d",&n,&m);
    for(i=2;i<=n;i++)
 {
  s=(s+m)%i;
 }
    printf("The winner is %dn", s+1);
 system("pause");
}


Related articles: