求解约瑟夫问题,J(n)表示n个人第二个给踢掉的与瑟夫问题的解,然后要求求解m次此嵌套函数
在网上搜到了两种办法,第一种直接通过递归求解约瑟夫的解
讨论如下,假设原先有2n个人。那么,在绕第一圈之后,留下:
[attach]76340[/attach]
此时剩下n个人,分别为 第一个人1(2×1-1),第二个人3(2×2-1)。。。第n个人2n-1(2n-1),假设知道此时(n个人)将得到的幸存者为x,那么有:第x个(2x-1),明显的,n个人里的第x个也就是之前在2n个人的时候的第2x-1个,此时可以建立起从J(2n)到J(n)的关系:J(2n) = 2 * J(n)-1,(n≥1)
同理,我们可以找到奇数时的关系:J(2n+1) = 2 * J(n)+1, (n≥1)
由上,有递推公式:
J(1)=1;
J(2n) = 2 * J(n)-1,(n≥1)
J(2n+1) = 2 * J(n)+1, (n≥1)
到这里,我们已经找出了一个可以解决问题的递推公式了,可以根据这个公式编程求解。
For example:
long Josephus(long n){
if (n==1)return 1;
else if (n%2) return 2*Josephus(n/2)+1;
else return 2*Josephus(n/2)-1;
return -1;
}
还有一个算法,不是太明白,先把代码放上过几天理解了再说
1 #include<iostream>
2 using namespace std;
3 long long aa[64];
4 long long power(long long n)//计算2的N次方的函数5 {
6 long long t;
7 if(n==0) return 1;
8 if(n==1) return 2;
9 if(n%2==0) return (t=power(n/2))*t;
10 if(n%2==1) return (t=power((n-1)/2))*t*2;
11 }
12 int main()
13 {
14 long long a,i,n,pre;
15
16 for(i = 0;i<=62;i++)
17 aa[i] = power(i);
18 while(cin>>a>>n)
19 {
20 while(n--)
21 {
22 pre = a;
23 for(i = 0;i <= 61;i++)
24 if(a>=aa[i] && a<aa[i+1])
25 break;
26 if(a >= aa[62] ) i=62;
27 a = (a-aa[i])*2+1;
28 if(a==pre) break;
29 }
30 cout << a << endl;
31
32 }
33 return 0;
34 }

浙公网安备 33010602011771号