• 【HDOJ】4043 FXTZ II


    1. 题目描述
    有n个球,第i个球的伤害值为$2^i-1, i in [1,n]$。有甲乙两个人,每次由甲选择n个球中的一个,用它以相同概率攻击自己或者乙,同时彻底消耗这个球。这样的攻击最多进行n次。
    一旦甲的伤害值高于乙,则甲输,否则甲胜。问甲胜的概率是多少。

    2. 基本思路
    还是一步步推导。令dp[k]表示共有k个球时甲胜的概率。
    egin{align}
        dp[1] &= frac{1}{2}    otag \
        dp[2] &= frac{1}{2} imes frac{1}{2} imes (1 + dp[1]) otag \
        dp[3] &= frac{1}{3} imes frac{1}{2} imes (1 + dp[1] + dp[2]) otag \
        dp[4] &= frac{1}{4} imes frac{1}{2} imes (1 + dp[1] + dp[2] + dp[3]) otag \
            &cdots otag \
        dp[n] &= frac{1}{n} imes frac{1}{2} imes (1 + Sigma_{i=1}^{n-1}dp[i])
    end{align}
    为什么上式成立,以$dp[3] = frac{1}{3} imes frac{1}{2} imes (1 + dp[1] + dp[2])$为例解释。
    $frac{1}{3} imes frac{1}{2}$表示在第k次取到第3个球的概率(该球一定攻击乙),$k in [1,3]$。
    此时,这个球一定属于乙(否则甲必输)并且从此时开始,无论后续的球如何安排,最终都是甲胜。
    然而,前k次一定满足甲胜,否则在$[1,k-1]$的某一次中,即停止游戏。
    当k=3时,概率为dp[2];
    当k=2时,概率为dp[1];
    当k=1时,概率为1。
    以此类推,dp[n]。

    3. 代码

     1 import java.lang.*;
     2 import java.io.*;
     3 import java.util.*;
     4 import java.math.BigInteger;
     5 
     6 
     7 public class Main {
     8     
     9     public static void main(String[] arg) throws java.lang.Exception {
    10         InputStream inputStream = System.in;
    11         OutputStream outputStream = System.out;
    12         InputReader in = new InputReader(inputStream);
    13         PrintWriter out = new PrintWriter(outputStream);
    14         TaskA solver = new TaskA();
    15         solver.solve(in, out);
    16         out.close();
    17     }
    18 }
    19 
    20 
    21     
    22 class TaskA {
    23     public final static int maxn = 505;
    24     BigInteger[] FZ = new BigInteger[maxn];
    25     BigInteger[] FM = new BigInteger[maxn];
    26     
    27     public TaskA() {
    28         init();
    29     }
    30     
    31     public void solve(InputReader in, PrintWriter out) {
    32         int t = in.nextInt();
    33         int n;
    34         
    35         while (t-- > 0) {
    36             n = in.nextInt();
    37             out.println(FZ[n].toString() + "/" + FM[n].toString());
    38         }
    39     }
    40     
    41     private void init() {
    42         BigInteger sfm = BigInteger.ONE, sfz = BigInteger.ONE;
    43         BigInteger fm, fz;
    44         BigInteger g, lcm;
    45         
    46         for (int i=1; i<=500; ++i) {
    47             fm = sfm.multiply(BigInteger.valueOf(i*2));
    48             fz = sfz;
    49             g = fz.gcd(fm);
    50             FZ[i] = fz.divide(g);
    51             FM[i] = fm.divide(g);
    52             // System.out.println(fz + "/" + fm);
    53             
    54             g = sfm.gcd(FM[i]);
    55             sfz = sfz.multiply(FM[i].divide(g))
    56                      .add( FZ[i].multiply(sfm.divide(g)) );
    57             sfm = FM[i].divide(g).multiply(sfm);
    58         }
    59     }
    60     
    61     private BigInteger A(int n, int m) {
    62         BigInteger ret = BigInteger.ONE;
    63         
    64         for (int i=n; i>n-m; --i)
    65             ret = ret.multiply(BigInteger.valueOf(i));
    66         
    67         return ret;
    68     }
    69 }
    70 
    71 class InputReader {
    72     public BufferedReader reader;
    73     public StringTokenizer tokenizer;
    74     
    75     public InputReader(InputStream stream) {
    76         reader = new BufferedReader(new InputStreamReader(stream), 32768);
    77         tokenizer = null;
    78     }
    79     
    80     public String next() {
    81         while (tokenizer==null || !tokenizer.hasMoreTokens()) {
    82             try {
    83                 tokenizer = new StringTokenizer(reader.readLine());
    84             } catch (IOException e) {
    85                 throw new RuntimeException(e);
    86             }
    87         }
    88         return tokenizer.nextToken();
    89     }
    90     
    91     public int nextInt() {
    92         return Integer.parseInt(next());
    93     }
    94     
    95     public long nextLong() {
    96         return Long.parseLong(next());
    97     }
    98 }

     

  • 相关阅读:
    【梦断代码】与我们队的相似之处
    梦断代码 之 你失败过吗
    梦断代码 之 程序人生
    C#中父类转换为子类
    C#中Dictionary泛型集合7种常见的用法
    Linux 常见命令 目录处理指令
    使用XSLT+XML生成网页
    我心目中的Asp.net核心对象
    配色速成
    VS.NET中JavaScript隐藏特性
  • 原文地址:https://www.cnblogs.com/bombe1013/p/5236763.html
Copyright © 2020-2023  润新知