其实这是一个约瑟夫问题的变种
首先我们先处理这样一个问题
已知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.
View Code

 

posted on 2014-11-07 16:24  acphile  阅读(145)  评论(0编辑  收藏  举报