其实这是一个约瑟夫问题的变种
首先我们先处理这样一个问题
已知n个人,编号0~n-1,每k人干掉一个,问最后留下来的是谁
当n,k非常大的时候,模拟是不行的,这时候我们考虑重编号
第1次退出的肯定是肯定是编号为k-1的人,这是我们对剩下的人重标号
k-->0 k+1--->1 ……k-2-->n-2 也就是原来编号xi=(新编号xi'+k) mod n
这样就变成同样一个问题
已知n-1个人,编号0~n-2,每k人干掉一个,问最后留下来的是谁
由此递推下去,显然最后留下来的人编号为0
然后我们由最后一次倒推,就可以知道,最后留下来的初始编号是什么
回到这道题来,我们正是利用这种思想,从后往前计算数学期望
不妨令一开始玩家编号改成0~n-1
设f[i,j]为第i次出队时,那个时候的编号为j的获胜概率
然后就可以很快解决了
1 var f:array[0..60,0..60] of double; 2 a:array[0..60] of longint; 3 i,n,m,j,k:longint; 4 5 begin 6 readln(n,m); 7 for i:=1 to m do 8 read(a[i]); 9 f[1,0]:=1; 10 for i:=2 to n do 11 for j:=0 to n-1 do 12 for k:=1 to m do 13 f[i,(j+a[k] ) mod i]:=f[i,(j+a[k]) mod i]+f[i-1,j]/m; 14 for i:=0 to n-1 do 15 begin 16 write(f[n,i]*100:0:2); 17 write('%'); 18 if i<>n-1 then write(' '); 19 end; 20 end.