题意:
n个人玩石头剪子布,每轮剩下的人同时出拳,如果出的拳有且只有两种,那么就可以淘汰掉输的人,否则不变。求只剩下一个人的期望轮数。
题解:
很简单的概率DP,但是对精度要求很高,long double 也不能满足要求,没办法只能先学java,写得丑请不要太介意……
设dp[i]表示剩下i个人的期望,那么dp[1]就等于0了。
对于其他的dp[i],有:
dp[i]=p1*(dp[i-1]+1)+p2*(dp[i-2]+1)+...+pi-1*(dp[1]+1)+(1-p1-p2-...-pi-1)*(dp[i]+1)
p1表示淘汰1个人的概率。
其中1也可以全部提出来做一个1,用java的BigDecimal时操作少一点。
//Time:203ms
//Memory:6640KB
//Length:1342B
import java.util.*;
import java.math.*;
import java.util.ArrayList;
public class Main
{
public static BigDecimal dp[]=new BigDecimal[110];
public static BigDecimal c[][]=new BigDecimal[110][110];
public static void init()
{
c[0][0]=new BigDecimal(1);
c[0][1]=new BigDecimal(0);
for(int i=1;i<=100;++i)
{
c[i][0]=new BigDecimal(1);
for(int j=1;j<=i;++j)
{
c[i][j]=c[i-1][j-1].add(c[i-1][j]);
}
c[i][i+1]=new BigDecimal(0);
}
}
public static void main(String []args)
{
int n,preci=100;
dp[1]=new BigDecimal(0);
Scanner scan=new Scanner(System.in);
n=scan.nextInt();
init();
for(int i=2;i<=n;++i)
{
dp[i]=new BigDecimal(0);
BigDecimal p=new BigDecimal(1);
BigDecimal tmp=new BigDecimal(1);
for(int j=2;j<=i;++j) tmp=tmp.multiply(BigDecimal.valueOf(3));
for(int j=1;i-j>=1;++j)
{
p=p.subtract(c[i][j].divide(tmp,preci,BigDecimal.ROUND_HALF_UP));
dp[i]=dp[i].add(dp[j].add(BigDecimal.ONE).divide(tmp,preci,BigDecimal.ROUND_HALF_UP).multiply(c[i][j]));
}
dp[i]=dp[i].add(p);
dp[i]=dp[i].divide(BigDecimal.ONE.subtract(p),preci,BigDecimal.ROUND_HALF_UP);
}
System.out.println(dp[n].divide(BigDecimal.ONE,10,BigDecimal.ROUND_HALF_UP));
return ;
}
}